Introduction
The Catenis API is organized around REST. The API has predictable, resource-oriented URLs, and uses HTTP response status codes to indicate the outcome of an API method request.
It uses built-in HTTP features, like HTTP verbs and headers, which are understood by off-the-shelf HTTP clients. It supports cross-origin resource sharing, allowing you to securely interact with the Catenis API from a client-side web application — though you should never expose your API access secret in any public website's client-side code.
A JSON is returned in response to any API method request, even when an error takes place.
Environments
The Catenis API ver. 0.13 is available in the following environments.
Sandbox
This is a non-production environment that connects with the testnet Bitcoin network.
Base API URL
https://sandbox.catenis.io/api/0.13/
Basic concepts
Catenis entities
Virtual device
The virtual device — or some times simply referred to as device — is the fundamental entity that is used to interact with the Catenis system.
Each virtual device has a unique device ID
, which is assigned by the system when a new virtual
device is created.
Optionally, a virtual device can also be identified by an end user provided product unique ID
.
Each virtual device also has a system assigned API access secret
, which is used for authenticating the virtual device
when making an API request.
An optional name
can also be assigned to a virtual device. That name, however, only serves as a label and
cannot be used to select or otherwise reference a specific virtual device.
Client
The client is the entity that maps to an end user. A client can have one or more virtual devices.
Like virtual devices, each client has a unique client ID
, which is assigned by the system when a new client is
created.
Each client is associated with a system provided user account. The client user account is used by the end user to access the system and do administrative tasks, like creating new virtual devices, and adding service credits.
Catenis node
The Catenis node is the entity used to aggregate the Catenis services for a specific region or user premises.
Catenis nodes are identified by their index. Currently, only one public, central Catenis node — referred to as the Catenis Hub node — is available. The Catenis Hub node has index 0.
Clients are defined within a given Catenis node. So, a Catenis node will typically have one or more clients.
Permission rights
Catenis provides a permission mechanism where a virtual device — the controlling device — can allow or deny other virtual devices — the controlled devices — to interact with it in a given predefined way. Such predefined controlled interactions are referred to as permission events.
Permission events
The following permission events are currently defined:
Event name | Description |
---|---|
receive-notify-new-msg |
Receive notification of new message from a device |
receive-notify-msg-read |
Receive notification of message read by a device |
receive-notify-asset-of |
Receive notification of asset received for assets issued by a device |
receive-notify-asset-from |
Receive notification of asset received from a device |
receive-notify-confirm-asset-of |
Receive notification of confirmation of pending asset issued by a device |
receive-notify-confirm-asset-from |
Receive notification of confirmation of pending asset transferred by a device |
send-read-msg-confirm |
Send read message confirmation to a device |
receive-msg |
Receive message from a device |
disclose-main-props |
Disclose device's main properties (name, product unique ID) to a device |
disclose-identity-info |
Disclose device's basic identification information to a device |
receive-asset-of |
Receive an amount of an asset issued by a device |
receive-asset-from |
Receive an amount of an asset from a device |
receive-nf-token-of |
Receive a non-fungible token issued by a device |
receive-nf-token-from |
Receive a non-fungible token from a device |
disclose-nf-token-ownership |
Disclose device's non-fungible token ownership status to a device |
A permission event is described as an action where the controlling device is the subject and the controlled device is the object of such action.
Thus, taking the receive-msg
permission event as an example, if a device is given allow right in regards to that
permission event, it means that the controlling device will be able to receive messages sent from that device. Otherwise
— if a device is given deny right instead —, the controlling device shall not receive any messages sent from
that device.
Permission levels
For a given pair of permission event and controlling device, the permission rights can be set at four different levels:
System - it is the default permission right.
Catenis node - it controls the permission right for all devices that belong to any client defined for that Catenis node.
Client - it controls the permission right for all devices that belong to this client.
Device - it controls the permission right for this specific device.
Permission right evaluation
For a given pair of permission event and controlling device, the effective permission right for a given (controlled) device is evaluated according to the following procedure:
Starting at the device level, we check if the permission right for that (controlled) device is set. If it is set, this is the permission right that is in effect.
Otherwise, we go to the level above, and check if the permission right for the client to which the (controlled) device belongs is set. If it is set, this is the permission right that is in effect.
Otherwise, we go to the level above, and check if the permission right for the Catenis node where the client to which the (controlled) device belongs is defined is set. If it is set, this is the permission right that is in effect.
Otherwise, whatever permission right that is set at the system level is what is in effect.
Authentication
General
Most Catenis API methods require authentication on each request. The authentication mechanism used is a SHA-256 Keyed-Hash Message Authentication Code (HMAC-SHA256). It is based on the AWS Signature version 4 authentication scheme, although it is not the same, and thus libraries that implement the AWS authentication scheme cannot be used with the Catenis API.
With HMAC-SHA256, the server and the client share a secret signing key. The signing key lives in the respective client application and is never transmitted across the line. Instead, the key is used to generate a hash for signing the message contents.
To authenticate and use the services provided by the Catenis API methods, one must have an active client account, and use one of their virtual devices to actually consume the service. The virtual device's device ID and API access secret are then used to generate the authentication token that needs to be sent with every request.
Public API methods
A few Catenis API methods are public and do not require any authentication. The end user can access these services by simply making a request to the API method's URL as he or she would normally do when accessing a Web page.
Unlike regular (private) API methods, public API methods are not called for a given virtual device. No virtual device is required, and the end user does not even need to have a Catenis client account.
Usage
To properly call a Catenis API method, the client application must authenticate the request before sending it, for which the following general steps must be taken:
- Constructs an HTTP request for the API method that needs to be called;
- Signs the request using the virtual device's API access secret;
- Adds an Authorization header containing, amongst other things, the virtual device's device ID and the calculated signature.
Alternatively, one of the supplied Catenis API client libraries can be used, which makes issuing and authenticating Catenis API requests much simpler.
Detailed specification
This section describes how to issue and authenticate an HTTP request that conforms with the Catenis HMAC-SHA256 authentication scheme used by the Catenis API.
HTTP headers
Not yet authenticated request (used in following examples):
POST /api/0.13/messages/log HTTP/1.1
Host: sandbox.catenis.io
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
X-BCoT-Timestamp: 20180127T121358Z
Content-Type: application/json; charset=utf-8
Connection: close
Content-Length: 95
{"message":"This is only a test","options":{"encoding":"utf8","encrypt":true,"storage":"auto"}}
The HTTP request that needs to be authenticated must include at least the following HTTP headers, known as the essential headers:
Header | Contents |
---|---|
Host |
The host name. Example: sandbox.catenis.io |
X-BCoT-Timestamp |
The current UTC time in ISO 8601 format. Example: 20170125T000000Z |
Aside from the essential headers, after the request is authenticated, it will include an HTTP Authorization header, since the authentication itself consists of adding that header to the request.
The following sections describe the elements that are needed for composing the contents of the Authorization header.
Conformed request
String literal:
"POST\n/api/0.13/message/send\nhost:api.catenis.com\nx-bcot-timestamp:20180127T121358Z\n\n792cdbeef04dc33e8ebb4974070ec5a75bd1e3a6c5ef49b1c3ec1b87152694c6\n"
Printed text:
POST
api/0.13/message/send
host:api.catenis.com
x-bcot-timestamp:20180127T121358Z
792cdbeef04dc33e8ebb4974070ec5a75bd1e3a6c5ef49b1c3ec1b87152694c6
The conformed request is defined as:
<http_verb> + "\n" + <api_endpoint_path> + "\n" + <essential_headers> + "\n" + <payload_hash> + "\n"
Where:
Term | Description |
---|---|
<http_verb> |
The HTTP method of the request. One of: GET , POST , PUT , HEAD , or DELETE . |
<api_endpoint_path> |
The complete path of the URL of the API method endpoint. Example: /api/0.13/message/send |
<essential_headers> |
A list showing the essential headers with their respective contents. Each item is defined as: <header_name> + ":" + <header_contents> + "\n" ; where <header_name> is the lowercase name of the header, and <header_contents> is the contents of the header. Example: host:sandbox.catenis.io\nx-bcot-timestamp:20170125T103246Z\n |
<payload_hash> |
Defined as: HEX(SHA256(<payload>)) ; where <payload> is the payload (or body) of the HTTP request. If the request has no payload, an empty string should be used in its place. |
String to sign
String literal:
"CTN1-HMAC-SHA256\n20180127T121358Z\n20180127/ctn1_request\n6c5a53a5aed35fe4dc27146c7d01d548cd810b644b0dcada1d1416fe82cad6f0\n"
Printed text:
CTN1-HMAC-SHA256
20180127T121358Z
20180127/ctn1_request
6c5a53a5aed35fe4dc27146c7d01d548cd810b644b0dcada1d1416fe82cad6f0
The string to sign is defined as:
"CTN1-HMAC-SHA256" + "\n" + <timestamp> + "\n" + <scope> + "\n" + <conformed_request_hash> + "\n"
Where:
Term | Description |
---|---|
<timestamp> |
Current UTC time in ISO 8601 format. Example: 20180127T121358Z |
<scope> |
Defined as: <date> + “/ctn1_request” ; where <date> is a date formatted as YYYYMMDD. Example: 20180127/ctn1_request |
<conformed_request_hash> |
Defined as: HEX(SHA256(<conformed_request>)) ; where <conformed_request> is the conformed request element as defined in the Conformed request section above. |
Signing key
String literal:
"\xe9\x94\x04\xc8\xbb\xc2\x5d\x02\x56\xff\xa5\x8f\x6e\x72\x17\x9d\xe5\xdc\x7f\x67\xf9\xe5\x8f\x84\x32\xaf\x76\x18\xbb\xb7\x99\xe5"
The signing key is defined as:
HMAC-SHA256(<date_key>, “ctn1_request”)
Term | Description |
---|---|
<date_key> |
Defined as: HMAC-SHA256(“CTN1" + <api_access_secret>, <scope_date>) ; where <api_access_secret> is the virtual device's API access secret, and <scope_date> is the <date> component of the <scope> element as defined in String to sign section above. |
Signature
String literal:
"70db4ecb53a69dfdc8dcef5934a4d12df93c14f3178fe7797261c4f66144a44b"
Printed text:
70db4ecb53a69dfdc8dcef5934a4d12df93c14f3178fe7797261c4f66144a44b
The signature is defined as:
HEX(HMAC-SHA256(<signing_key>, <string_to_sign>))
Term | Description |
---|---|
<signing_key> |
The signing key element as defined in the Signing key section above |
<string_to_sign> |
The string to sign element as defined in the String to sign section above |
Authorization header
Authenticated request:
POST /api/0.13/messages/log HTTP/1.1
Host: sandbox.catenis.io
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
X-BCoT-Timestamp: 20180127T121358Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180127/ctn1_request,Signature=70db4ecb53a69dfdc8dcef5934a4d12df93c14f3178fe7797261c4f66144a44b
Content-Type: application/json; charset=utf-8
Connection: close
Content-Length: 95
{"message":"This is only a test","options":{"encoding":"utf8","encrypt":true,"storage":"auto"}}
The contents of the Authorization header is defined as:
"CTN1-HMAC-SHA256" + <space> + "Credential=" + <device_id> + "/" + <scope> + "," + "Signature=" + <signature>
Where:
Term | Description |
---|---|
<space> |
A sequence of one or more whitespace characters. |
<device_id> |
The virtual device's device ID. Example: dnN3Ea43bhMTHtTvpytS |
<scope> |
The <scope> element as defined in the String to sign section above. Example: 20180127/ctn1_request |
<signature> |
The signature element as defined in the Signature section above. |
Authentication related errors
Client libraries
To make it easier for developers to interact with the Catenis API and overcome the hurdles of authenticating each request, Blockchain of Things provide open-source client libraries for different programming languages and environments.
The following libraries are currently available:
Paw extensions
Aside from the Catenis API client libraries listed above, Blockchain of Things have also made available a set of customized Paw extensions that can be used to facilitate the creation and use of Catenis API requests from within Paw on a Mac, allowing for easy prototyping and testing of the Catenis API methods.
API methods
The following is a comprehensive list of the methods that comprise the Catenis API ver. 0.13.
- Message methods
- Asset methods
- Non-fungible asset methods
- Issue Non-Fungible Asset
- Reissue Non-Fungible Asset
- Retrieve Non-Fungile Asset Issuance Progress
- Retrieve Non-Fungible Token
- Retrieve Non-Fungible Token Retrieval Progress
- Transfer Non-Fungible Token
- Retrieve Non-Fungible Token Transfer Progress
- List Owned Non-Fungible Tokens
- Get Non-Fungible Token Owner
- Check Non-Fungible Token Ownership
- Asset export methods
- Permission methods
- Notification methods
- Miscellaneous methods
Asset Export Outcome
Retrieve the current information about the outcome of an asset export.
Sample request:
GET /api/0.13/assets/aH2AkrrL55GcThhPNa3J/export/ethereum HTTP/1.1
X-BCoT-Timestamp: 20210810T195125Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20210810/ctn1_request, Signature=2d30b89906b459b0ebc5c5df6bf12b862b59851530a636c11320d2fd89c5614e
Host: localhost:3000
Connection: close
User-Agent: Paw/3.2.3 (Macintosh; OS X/11.5.0) GCDHTTPRequest
curl "http://localhost:3000/api/0.13/assets/aH2AkrrL55GcThhPNa3J/export/ethereum" \
-H 'X-BCoT-Timestamp: 20210810T195231Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20210810/ctn1_request, Signature=3fc5a2654f845c15b0fa731094e9ac8b7f0aa1b2f657580c162985e31d3b5438'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aH2AkrrL55GcThhPNa3J';
var foreignBlockchain = 'ethereum';
ctnApiClient.assetExportOutcome(assetId, foreignBlockchain, function(error, data) {
if (error) {
// Process error
}
else {
// Process returned data
if (data.status === 'success') {
// Asset successfully exported
console.log('Foreign token ID (address):', data.token.id);
}
else if (data.status === 'pending') {
// Final asset export state not yet reached
}
else {
// Asset export has failed. Process error
console.error('Error executing foreign blockchain transaction:', data.foreignTransaction.error);
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aH2AkrrL55GcThhPNa3J';
var foreignBlockchain = 'ethereum';
ctnApiClient.assetExportOutcome(assetId, foreignBlockchain, function(error, data) {
if (error) {
// Process error
}
else {
// Process returned data
if (data.status === 'success') {
// Asset successfully exported
console.log('Foreign token ID (address):', data.token.id);
}
else if (data.status === 'pending') {
// Final asset export state not yet reached
}
else {
// Asset export has failed. Process error
console.error('Error executing foreign blockchain transaction:', data.foreignTransaction.error);
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$assetId = 'aH2AkrrL55GcThhPNa3J';
$foreignBlockchain = 'ethereum';
try {
$data = $ctnApiClient->assetExportOutcome($assetId, $foreignBlockchain);
// Process returned data
if ($data->status === 'success') {
// Asset successfully exported
echo 'Foreign token ID (address): ' . $data->token->id . PHP_EOL;
} elseif ($data->status === 'pending') {
// Final asset export state not yet reached
} else {
// Asset export has failed. Process error
echo 'Error executing foreign blockchain transaction: ' . $data->foreignTransaction->error . PHP_EOL;
}
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let asset_id = "aH2AkrrL55GcThhPNa3J";
let result = ctn_client.asset_export_outcome(
asset_id,
ForeignBlockchain::Ethereum,
)?;
match result.status {
AssetExportStatus::Success => {
// Asset successfully exported
println!("Foreign token ID (address): {}", result.token.id.unwrap());
},
AssetExportStatus::Pending => {
// Final asset export state not yet reached
},
AssetExportStatus::Error => {
// Asset export has failed. Process error
println!(
"Error executing foreign blockchain transaction: {}",
result.foreign_transaction.error.unwrap()
);
},
}
Ok(())
}
Accessibility
Private
Request
GET /assets/:assetId
/export/:foreignBlockchain
Parameters
- URL parameters:
assetId
: The ID of the asset that was exported.foreignBlockchain
: The key identifying the foreign blockchain. Valid options:ethereum
,binance
,polygon
.
Sample response:
{
"status": "success",
"data": {
"foreignTransaction": {
"txid": "0x1f14474f441557056055a186ccf6839bd4dfce79e0b134d77084b6ef4274dc1a",
"isPending": false,
"success": true
},
"token": {
"name": "Catenis test token #10",
"symbol": "CTK10",
"id": "0x537580164Ba9DB2e8C254a38E254ce15d07fDef9"
},
"status": "success",
"date": "2021-08-03T18:41:27.679Z"
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
foreignTransaction |
Object | Information about the transaction issued on the foreign blockchain to create the resulting foreign token. |
txid |
String | The ID (or hash) of the foreign blockchain transaction. |
isPending |
Boolean | Indicates whether the foreign blockchain transaction is yet to be executed. |
success |
Boolean | (only returned after the foreign blockchain transaction is executed) Indicates whether the foreign blockchain transaction has been successfully executed or not. |
error |
String | (only returned if the foreign blockchain transaction's execution has failed) An error message describing what went wrong when executing the transaction. |
token |
Object | Information about the resulting foreign token. |
name |
String | The token name. |
symbol |
String | The token symbol. |
id |
String | (only returned if the asset is successfully export) The ID (or address) of the token on the foreign blockchain. |
status |
String | The current state of the asset export. One of: pending , success , or error |
date |
String | ISO 8601 formatted date and time when the asset has been exported. |
Possible errors
Asset Migration Outcome
Retrieve the current information about the outcome of an asset migration.
Sample request:
GET /api/0.13/assets/migrations/gq8x3efLpEXTkGQchHTb HTTP/1.1
X-BCoT-Timestamp: 20210810T211045Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20210810/ctn1_request, Signature=60c4f0069c227fca8780ecb263cac1b98f40d15416a21c54cd6c1498644a7915
Host: localhost:3000
Connection: close
User-Agent: Paw/3.2.3 (Macintosh; OS X/11.5.0) GCDHTTPRequest
curl "http://localhost:3000/api/0.13/assets/migrations/gq8x3efLpEXTkGQchHTb" \
-H 'X-BCoT-Timestamp: 20210810T211101Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20210810/ctn1_request, Signature=97a742d0245a5b078bccaed62724d725826ba87d92ae0a6d160abe26ab0958af'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var migrationId = 'gq8x3efLpEXTkGQchHTb';
ctnApiClient.assetMigrationOutcome(migrationId, function(error, data) {
if (error) {
// Process error
}
else {
// Process returned data
if (data.status === 'success') {
// Asset amount successfully migrated
console.log('Asset amount successfully migrated');
}
else if (data.status === 'pending') {
// Final asset migration state not yet reached
}
else {
// Asset migration has failed. Process error
if (data.catenisService.error) {
console.error('Error executing Catenis service:', data.catenisService.error);
}
if (data.foreignTransaction.error) {
console.error('Error executing foreign blockchain transaction:', data.foreignTransaction.error);
}
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var migrationId = 'gq8x3efLpEXTkGQchHTb';
ctnApiClient.assetMigrationOutcome(migrationId, function(error, data) {
if (error) {
// Process error
}
else {
// Process returned data
if (data.status === 'success') {
// Asset amount successfully migrated
console.log('Asset amount successfully migrated');
}
else if (data.status === 'pending') {
// Final asset migration state not yet reached
}
else {
// Asset migration has failed. Process error
if (data.catenisService.error) {
console.error('Error executing Catenis service:', data.catenisService.error);
}
if (data.foreignTransaction.error) {
console.error('Error executing foreign blockchain transaction:', data.foreignTransaction.error);
}
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$migrationId = 'gq8x3efLpEXTkGQchHTb';
try {
$data = $ctnApiClient->assetMigrationOutcome($migrationId);
// Process returned data
if ($data->status === 'success') {
// Asset amount successfully migrated
echo 'Asset amount successfully migrated' . PHP_EOL;
} elseif ($data->status === 'pending') {
// Final asset migration state not yet reached
} else {
// Asset migration has failed. Process error
if (isset($data->catenisService->error)) {
echo 'Error executing Catenis service: ' . $data->catenisService->error . PHP_EOL;
}
if (isset($data->foreignTransaction->error)) {
echo 'Error executing foreign blockchain transaction: ' . $data->foreignTransaction->error . PHP_EOL;
}
}
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let migration_id = "gq8x3efLpEXTkGQchHTb";
let result = ctn_client.asset_migration_outcome(
migration_id,
)?;
match result.status {
AssetMigrationStatus::Success => {
// Asset amount successfully migrated
println!("Asset amount successfully migrated");
},
AssetMigrationStatus::Pending => {
// Final asset migration state not yet reached
},
_ => {
// Asset migration has failed. Process error
if let Some(error) = result.catenis_service.error {
println!("Error executing Catenis service: {}", error);
}
if let Some(error) = result.foreign_transaction.error {
println!("Error executing foreign blockchain transaction: {}", error);
}
},
}
Ok(())
}
Accessibility
Private
Request
GET /assets/migrations/:migrationId
Parameters
- URL parameters:
migrationId
: The ID of the asset migration.
Sample response:
{
"status": "success",
"data": {
"assetId": "aH2AkrrL55GcThhPNa3J",
"foreignBlockchain": "ethereum",
"direction": "outward",
"amount": 10,
"catenisService": {
"status": "fulfilled",
"txid": "61fcb4feb64ecf3b39b4bb6d64eb9cc68a58ba1d892f981ef568d07b7aa11fdf"
},
"foreignTransaction": {
"txid": "0x212ab54f136a6fc1deae9ec217ef2d0417615178777131e8bb6958447fd20fe7",
"isPending": false,
"success": true
},
"status": "success",
"date": "2021-08-03T18:51:55.591Z"
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
assetId |
String | The ID of the asset the amount of which has been migrated. |
foreignBlockchain |
String | The key identifying the foreign blockchain to/from where the asset amount has been migrated. One of: ethereum , binance , or polygon . |
direction |
String | The direction of the migration. One of: outward or inward . |
amount |
Number | The migrated asset amount. |
catenisService |
Object | Information about the execution of the migrate asset Catenis service. |
status |
String | The current state of the service's execution. One of: awaiting , failure , or fulfilled . |
txid |
String | (only returned if the service is successfully fulfilled) The ID of the Catenis transaction issued to fulfill the service. |
error |
String | (only returned if the service's execution has failed) An error message describing what went wrong when executing the service. |
foreignTransaction |
Object | Information about the transaction issued on the foreign blockchain to mint/burn the amount of the foreign token. |
txid |
String | The ID (or hash) of the foreign blockchain transaction. |
isPending |
Boolean | Indicates whether the foreign blockchain transaction is yet to be executed. |
success |
Boolean | (only returned after the foreign blockchain transaction is executed) Indicates whether the foreign blockchain transaction has been successfully executed or not. |
error |
String | (only returned if the foreign blockchain transaction's execution has failed) An error message describing what went wrong when executing the transaction. |
status |
String | The current state of the asset migration. One of: pending , interrupted , success , or error . |
date |
String | ISO 8601 formatted date and time when the asset amount has been migrated. |
Possible errors
Check Effective Permission Right
Checks the effective permission right that is currently applied to a given virtual device for a specified permission event.
The virtual device issuing the request acts as the controlling device. Thus the permission right returned is for the pair composed of the permission event specified in the API request and the virtual device issuing the request.
Sample request:
GET /api/0.13/permission/events/receive-msg/rights/dv3htgvK7hjnKx3617Re HTTP/1.1
X-BCoT-Timestamp: 20180219T104640Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=0753e60d70a02448386d6485ab6d7ca34b1faa851bf71b6219256ae5059dfa09
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/permission/events/receive-msg/rights/dv3htgvK7hjnKx3617Re" \
-H 'X-BCoT-Timestamp: 20180219T104602Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=521537ae60e0cc6099c459220702aad51d68c7c6d82328d6df3d3dc122de8683'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var checkDeviceId = 'dv3htgvK7hjnKx3617Re';
ctnApiClient.checkEffectivePermissionRight('receive_msg', checkDeviceId, false, function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
var deviceId = Object.keys(data)[0];
console.log('Effective right for device', deviceId, ':', data[deviceId]);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var checkDeviceId = 'dv3htgvK7hjnKx3617Re';
ctnApiClient.checkEffectivePermissionRight('receive_msg', checkDeviceId, false, function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
var deviceId = Object.keys(data)[0];
console.log('Effective right for device', deviceId, ':', data[deviceId]);
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$checkDeviceId = 'dv3htgvK7hjnKx3617Re';
try {
$data = $ctnApiClient->checkEffectivePermissionRight('receive-msg', $checkDeviceId);
// Process returned data
$deviceId = array_keys(get_object_vars($data))[0];
echo 'Effective right for device ' . $deviceId . ': ' . $data->$deviceId . PHP_EOL;
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let check_device = DeviceId {
id: String::from("dv3htgvK7hjnKx3617Re"),
is_prod_unique_id: None,
};
let result = ctn_client.check_effective_permission_right(
PermissionEvent::ReceiveMsg,
check_device,
)?;
let (device_id, right) = result.iter().next().unwrap();
println!("Effective right for device {}: {:?}", device_id, right);
Ok(())
}
Accessibility
Private
Request
GET /permission/events/:eventName
/rights/:deviceId
Parameters
URL parameters:
eventName
: The name of the permission event the permission right set for which should be retrieved.deviceId
: The ID of the virtual device the permission right applied to which should be retrieved. Should be a device ID unlessisProdUniqueId
is set. The special valueself
can be used in place of the device ID of the virtual device issuing the request.
Query string parameters:
isProdUniqueId
: (optional, default:false
) Indicates whether the supplied ID is a product unique ID.
Sample response:
{
"status": "success",
"data": {
"dv3htgvK7hjnKx3617Re": "allow"
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. In this particular case, it is an object that works as a dictionary where its single property is the device ID of the device for which the effective permission right is being checked, and its value is the permission right itself. |
<check_device_ID> |
String | The permission right that is currently in effective for the virtual device the device ID of which is this property's name. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid device Invalid parameters: <param_list> |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
Check Non-Fungible Token Ownership
Verifies if a virtual device is the current owner of a single or multiple non-fungible tokens.
Sample request:
POST /api/0.13/assets/non-fungible/tokens/ownership HTTP/1.1
X-BCoT-Timestamp: 20221122T124935Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20221122/ctn1_request, Signature=d4746d5da8a92a0d0ef02aa95476ef75d8a9b8d78d47a254c1f92ea63faa556f
Content-Type: application/json; charset=utf-8
Host: localhost:3000
Connection: close
User-Agent: RapidAPI/4.0.0 (Macintosh; OS X/13.0.1) GCDHTTPRequest
Content-Length: 107
{"device":{"id":"drc3XdxNtzoucpw9xiRp"},"nonFungibleTokens":{"id":"aiqXDyh7hhukwxFhR69x","isAssetId":true}}
curl -X "POST" "http://localhost:3000/api/0.13/assets/non-fungible/tokens/ownership" \
-H 'X-BCoT-Timestamp: 20221122T125108Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20221122/ctn1_request, Signature=0084cca819b1de1a9f034a203ebce8c16bc0077558cdd1bc9761a88e081762b7' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"device": {
"id": "drc3XdxNtzoucpw9xiRp"
},
"nonFungibleTokens": {
"id": "aiqXDyh7hhukwxFhR69x",
"isAssetId": true
}
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var checkDeviceId = 'drc3XdxNtzoucpw9xiRp';
var assetId = 'aiqXDyh7hhukwxFhR69x';
ctnApiClient.checkNonFungibleTokenOwnership({
id: checkDeviceId,
isProdUniqueId: false
}, {
id: assetId,
isAssetId: true
},
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Non-fungible tokens owned:', data.tokensOwned);
console.log('Non-fungible tokens not yet confirmed:', data.tokensUnconfirmed);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var checkDeviceId = 'drc3XdxNtzoucpw9xiRp';
var assetId = 'aiqXDyh7hhukwxFhR69x';
ctnApiClient.checkNonFungibleTokenOwnership({
id: checkDeviceId,
isProdUniqueId: false
}, {
id: assetId,
isAssetId: true
},
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Non-fungible tokens owned:', data.tokensOwned);
console.log('Non-fungible tokens not yet confirmed:', data.tokensUnconfirmed);
}
});
Accessibility
Private
Request
POST assets/non-fungible/tokens/ownership
Parameters
- Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
device |
Object | The virtual device to check if it has ownership. |
id |
String | The ID of the device. Should be a device ID unless isProdUniqueId is set. |
isProdUniqueId |
Boolean | (optional, default: false ) Indicates whether the supplied ID is a product unique ID. |
nonFungibleTokens |
Object | The non-fungible tokens to be verified. |
id |
String | Either the ID of the single non-fungible token to be verified, or the ID of the non-fungible asset the non-fungible tokens of which should be verified. |
isAssetId |
Boolean | (optional, default: false ) Indicates whether the specified ID is a non-fungible asset ID. Otherwise, it should be interpreted as a non-fungible token ID. |
Sample response:
{
"status": "success",
"data": {
"tokensOwned": 4,
"tokensUnconfirmed": 0
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
tokensOwned |
Number | Number of non-fungible tokens, out of those that have been verified, that are owned by the specified virtual device. |
tokensUnconfirmed |
Number | Number of non-fungible tokens, out of the owned ones, that are not yet confirmed. |
Possible errors
Export Asset
Export an asset to a foreign blockchain, by creating a new (ERC-20 compliant) token on that blockchain.
Sample request:
POST /api/0.13/assets/aH2AkrrL55GcThhPNa3J/export/ethereum HTTP/1.1
X-BCoT-Timestamp: 20210809T144134Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20210809/ctn1_request, Signature=87ed19ecefc670d61d4d85c0da80b608fc102a060e45c3d5caa5057eefc33d13
Content-Type: application/json; charset=utf-8
Host: localhost:3000
Connection: close
User-Agent: Paw/3.2.3 (Macintosh; OS X/11.5.0) GCDHTTPRequest
Content-Length: 60
{"token":{"name":"Catenis test token #10","symbol":"CTK10"}}
curl -X "POST" "http://localhost:3000/api/0.13/assets/aH2AkrrL55GcThhPNa3J/export/ethereum" \
-H 'X-BCoT-Timestamp: 20210809T144203Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20210809/ctn1_request, Signature=989280734b7ebf40057ec305d02af8d2d899f78cddcfca1ff4d30c652a3b8dc6' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"token": {
"name": "Catenis test token #10",
"symbol": "CTK10"
}
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aH2AkrrL55GcThhPNa3J';
var foreignBlockchain = 'ethereum';
ctnApiClient.exportAsset(assetId, foreignBlockchain, {
name: 'Catenis test token #10',
symbol: 'CTK10'
}, function (error, data) {
if (error) {
// Process error
}
else {
// Process returned data
console.log('Pending asset export:', data);
// Start polling for asset export outcome
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aH2AkrrL55GcThhPNa3J';
var foreignBlockchain = 'ethereum';
ctnApiClient.exportAsset(assetId, foreignBlockchain, {
name: 'Catenis test token #10',
symbol: 'CTK10'
}, function (error, data) {
if (error) {
// Process error
}
else {
// Process returned data
console.log('Pending asset export:', data);
// Start polling for asset export outcome
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$assetId = 'aH2AkrrL55GcThhPNa3J';
$foreignBlockchain = 'ethereum';
try {
$data = $ctnApiClient->exportAsset($assetId, $foreignBlockchain, [
'name' => 'Catenis test token #10',
'symbol' => 'CTK10'
]);
// Process returned data
echo 'Pending asset export: ' . print_r($data, true);
// Start polling for asset export outcome
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let asset_id = "aH2AkrrL55GcThhPNa3J";
let result = ctn_client.export_asset(
asset_id,
ForeignBlockchain::Ethereum,
NewForeignTokenInfo {
name: String::from("Catenis test token #10"),
symbol: String::from("CTK10"),
},
None,
)?;
println!("Pending asset export: {:?}", result);
// Start polling for asset export outcome
Ok(())
}
Accessibility
Private
Request
POST /assets/:assetId
/export/:foreignBlockchain
Parameters
URL parameters:
assetId
: The ID of the asset to export.foreignBlockchain
: The key identifying the foreign blockchain. Valid options:ethereum
,binance
,polygon
.
Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
token |
Object | |
name |
String | The name of the token to be created on the foreign blockchain. |
symbol |
String | The symbol of the token to be created on the foreign blockchain. |
options |
Object | (optional) |
consumptionProfile |
String | (optional) Name of the foreign blockchain's native coin consumption profile to use. Valid options: fastest , fast , average , slow . |
estimateOnly |
Boolean | (optional, default: false ) When set, indicates that no asset export should be executed but only the estimated price (in the foreign blockchain's native coin) to fulfill the operation should be returned. |
Sample response (regular export):
{
"status": "success",
"data": {
"foreignTransaction": {
"txid": "0x1f14474f441557056055a186ccf6839bd4dfce79e0b134d77084b6ef4274dc1a",
"isPending": true
},
"token": {
"name": "Catenis test token #10",
"symbol": "CTK10"
},
"status": "pending",
"date": "2021-08-03T18:41:11.781Z"
}
}
Sample response (estimate only):
{
"status": "success",
"data": {
"estimatedPrice": "0.05850782"
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
foreignTransaction |
Object | (not returned for estimate only) Information about the transaction issued on the foreign blockchain to create the resulting foreign token. |
txid |
String | The ID (or hash) of the foreign blockchain transaction. |
isPending |
Boolean | Indicates whether the foreign blockchain transaction is yet to be executed. |
success |
Boolean | (only returned after the foreign blockchain transaction is executed) Indicates whether the foreign blockchain transaction has been successfully executed or not. |
error |
String | (only returned if the foreign blockchain transaction's execution has failed) An error message describing what went wrong when executing the transaction. |
token |
Object | (not returned for estimate only) Information about the resulting foreign token. |
name |
String | The token name. |
symbol |
String | The token symbol. |
id |
String | (only returned if the asset is successfully export) The ID (or address) of the token on the foreign blockchain. |
status |
String | (not returned for estimate only) The current state of the asset export. One of: pending , success , or error . |
date |
String | (not returned for estimate only) ISO 8601 formatted date and time when the asset has been exported. |
estimatedPrice |
String | (only returned for estimate only) A text value representing the price, in the foreign blockchain's native coin, required to execute the foreign blockchain transaction. |
Possible errors
Get Asset Balance
Gets the current balance of a given asset held by the device.
Sample request:
GET /api/0.13/assets/aQjlzShmrnEZeeYBZihc/balance HTTP/1.1
X-BCoT-Timestamp: 20180417T165555Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=0531b1ce00b03de1ca707db48fd2474328e21fdb6930b8661a4608e8fe735b84
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/assets/aQjlzShmrnEZeeYBZihc/balance" \
-H 'X-BCoT-Timestamp: 20180417T165613Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=2f85718595bc2633e13b21315babeb00b60327b317e3c56dab3865f2aa29115c'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aQjlzShmrnEZeeYBZihc';
ctnApiClient.getAssetBalance(assetId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Current asset balance:', data.balance.total);
console.log('Amount not yet confirmed:', data.balance.unconfirmed);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aQjlzShmrnEZeeYBZihc';
ctnApiClient.getAssetBalance(assetId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Current asset balance:', data.balance.total);
console.log('Amount not yet confirmed:', data.balance.unconfirmed);
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$assetId = 'aQjlzShmrnEZeeYBZihc';
try {
$data = $ctnApiClient->getAssetBalance($assetId);
// Process returned data
echo 'Current asset balance: ' . $data->balance->total . PHP_EOL;
echo 'Amount not yet confirmed: ' . $data->balance->unconfirmed . PHP_EOL;
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let asset_id = "aQjlzShmrnEZeeYBZihc";
let result = ctn_client.get_asset_balance(
asset_id,
)?;
println!("Current asset balance: {}", result.total);
println!("Amount not yet confirmed: {}", result.unconfirmed);
Ok(())
}
Accessibility
Private
Request
GET /assets/:assetId
/balance
Parameters
- URL parameters:
assetId
: The ID of the asset to get balance.
Sample response:
{
"status": "success",
"data": {
"total": 1145.75,
"unconfirmed": 0
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
total |
Number | The current balance of the asset held by the device that issues the request. |
unconfirmed |
Number | The amount from the balance that is not yet confirmed. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid asset ID Invalid parameters: <param_list> |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
Get Non-Fungible Token Owner
Identifies the virtual device that currently owns a given non-fungible token.
Sample request:
GET /api/0.13/assets/non-fungible/tokens/twy3fNwmZjkRaawcMpmP/owner HTTP/1.1
X-BCoT-Timestamp: 20221121T151617Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20221121/ctn1_request, Signature=3e984242fe184d87e5f069d736659432d46084b4060940bf2097d293acdfdf41
Host: localhost:3000
Connection: close
User-Agent: RapidAPI/4.0.0 (Macintosh; OS X/13.0.1) GCDHTTPRequest
curl "http://localhost:3000/api/0.13/assets/non-fungible/tokens/twy3fNwmZjkRaawcMpmP/owner" \
-H 'X-BCoT-Timestamp: 20221121T215036Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20221121/ctn1_request, Signature=551664e5235b1ca8dfe10b13077c3d1dc88e0b2fae39d52ad53c8fc267ceb15f'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var tokenId = 'twy3fNwmZjkRaawcMpmP';
ctnApiClient.getNonFungibleTokenOwner(tokenId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Owning device:', data.owner);
console.log('Is confirmed:', data.isConfirmed);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var tokenId = 'twy3fNwmZjkRaawcMpmP';
ctnApiClient.getNonFungibleTokenOwner(tokenId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Owning device:', data.owner);
console.log('Is confirmed:', data.isConfirmed);
}
});
Accessibility
Private
Request
GET assets/non-fungible/tokens/:tokenId
/owner
Parameters
- URL parameters:
tokenId
: The ID of the non-fungible token the owner of which should be identified.
Sample response:
{
"status": "success",
"data": {
"owner": {
"deviceId": "drc3XdxNtzoucpw9xiRp",
"name": "TstDev1",
"prodUniqueId": "ABC123"
},
"isConfirmed": true
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
owner |
Object | The virtual device that currently owns the non-fungible token — owning device. |
deviceId |
String | The device ID of the owning device. |
name |
String | (only returned if the owning device has this data, and the virtual device issuing the request has the necessary permission right) The name of the owning device. |
prodUniqueId |
String | (only returned if the owning device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the owning device. |
isConfirmed |
Boolean | Indicates whether the blockchain transaction used to transfer the non-fungible token has already been confirmed. |
Possible errors
Issue Asset
Issues an amount of a new asset.
Sample request:
POST /api/0.13/assets/issue/ HTTP/1.1
X-BCoT-Timestamp: 20180416T192026Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180416/ctn1_request, Signature=ca4df849242d5b66c45d24c3dd2f8810f7063f4bf1df1555aa95d18405b7b5dd
Content-Type: application/json; charset=utf-8
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
Content-Length: 114
{"assetInfo":{"name":"XYZ001","description":"Testing asset #1","canReissue":true,"decimalPlaces":2},"amount":1200}
curl -X "POST" "https://sandbox.catenis.io/api/0.13/assets/issue/" \
-H 'X-BCoT-Timestamp: 20180416T191501Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180416/ctn1_request, Signature=fd75cb18eb60c6afa8c5be53dadf1937b08c131d39b20fce19badb285bdb79cc' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"amount": 1200,
"assetInfo": {
"decimalPlaces": 2,
"name": "XYZ001",
"description": "Testing asset #1",
"canReissue": true
}
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.issueAsset({
name: 'XYZ001'
description: 'Testing asset #1'
canReissue: true
decimalPlaces: 2
}, 1200.00, null,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('ID of newly issued asset:', data.assetId);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.issueAsset({
name: 'XYZ001'
description: 'Testing asset #1'
canReissue: true
decimalPlaces: 2
}, 1200.00, null,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('ID of newly issued asset:', data.assetId);
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
try {
$data = $ctnApiClient->issueAsset([
'name' => 'XYZ001',
'description' => 'Testing asset #1',
'canReissue' => true,
'decimalPlaces' => 2
], 1200.00, null);
// Process returned data
echo 'ID of newly issued asset: ' . $data->assetId . PHP_EOL;
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let result = ctn_client.issue_asset(
NewAssetInfo {
name: String::from("XYZ001"),
description: Some(String::from("Testing asset #1'")),
can_reissue: true,
decimal_places: 2,
},
1_200.0,
None,
)?;
println!("ID of newly issued asset: {}", result.asset_id);
Ok(())
}
Accessibility
Private
Request
POST /assets/issue
Parameters
- Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
assetInfo |
Object | |
name |
String | The name of the asset to create. |
description |
String | (optional) A description of the asset to create. |
canReissue |
Boolean | Indicates whether more units of this asset can be issued at another time. |
decimalPlaces |
Number | The maximum number of decimal places that can be used to specify a fractional amount of this asset. Must be an integer value between 0 and 7. |
amount |
Number | The amount of asset to issue. |
holdingDevice |
Object | (optional) Virtual device for which the asset is issued and that shall hold the issued amount. |
id |
String | The ID of the holding device. Should be a device ID unless isProdUniqueId is set. |
isProdUniqueId |
Boolean | (optional, default: false ) Indicates whether the supplied ID is a product unique ID. |
Sample response:
{
"status": "success",
"data": {
"assetId": "aQjlzShmrnEZeeYBZihc"
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
assetId |
String | ID of the newly issued asset. |
Possible errors
Issue Non-Fungible Asset
Creates a new non-fungible asset, and issues its initial non-fungible tokens.
Sample request (initial call):
POST /api/0.13/assets/non-fungible/issue HTTP/1.1
X-BCoT-Timestamp: 20220816T184259Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220816/ctn1_request, Signature=bbbde6e3ece3d8df044ecf68a291c26868e50faff512dce5f6de2d67da39451f
Content-Type: application/json; charset=utf-8
Host: localhost:3000
Connection: close
User-Agent: Paw/3.3.6 (Macintosh; OS X/12.5.0) GCDHTTPRequest
Content-Length: 584
{"assetInfo":{"name":"Catenis NFA 9","description":"Non-fungible asset #9 for testing","canReissue":true},"encryptNFTContents":true,"nonFungibleTokens":[{"metadata":{"name":"NFA9 NFT 1","description":"First token of Catenis non-fungible asset #9"},"contents":{"data":"Contents of first token of Catenis non-fungible asset #9","encoding":"utf8"}},{"metadata":{"name":"NFA9 NFT 2","description":"Second token of Catenis non-fungible asset #9"},"contents":{"data":"Here is the contents of the second token of Catenis non-fungible asset #9 (part #1)","encoding":"utf8"}}],"isFinal":false}
curl -X "POST" "http://localhost:3000/api/0.13/assets/non-fungible/issue" \
-H 'X-BCoT-Timestamp: 20220816T184259Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220816/ctn1_request, Signature=bbbde6e3ece3d8df044ecf68a291c26868e50faff512dce5f6de2d67da39451f' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"assetInfo": {
"name": "Catenis NFA 9",
"canReissue": true,
"description": "Non-fungible asset #9 for testing"
},
"encryptNFTContents": true,
"nonFungibleTokens": [
{
"metadata": {
"name": "NFA9 NFT 1",
"description": "First token of Catenis non-fungible asset #9"
},
"contents": {
"data": "Contents of first token of Catenis non-fungible asset #9",
"encoding": "utf8"
}
},
{
"metadata": {
"name": "NFA9 NFT 2",
"description": "Second token of Catenis non-fungible asset #9"
},
"contents": {
"data": "Here is the contents of the second token of Catenis non-fungible asset #9 (part #1)",
"encoding": "utf8"
}
}
],
"isFinal": false
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.issueNonFungibleAsset({
assetInfo: {
name: 'Catenis NFA 9',
description: 'Non-fungible asset #9 for testing',
canReissue: true
},
encryptNFTContents: true
}, [{
metadata: {
name: 'NFA9 NFT 1',
description: 'First token of Catenis non-fungible asset #9'
},
contents: {
data: 'Contents of first token of Catenis non-fungible asset #9',
encoding: 'utf8'
}
}, {
metadata: {
name: 'NFA9 NFT 2',
description: 'Second token of Catenis non-fungible asset #9'
},
contents: {
data: 'Here is the contents of the second token of Catenis non-fungible asset #9 (part #1)',
encoding: 'utf8'
}
}],
false,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Continuation token:', data.continuationToken);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.issueNonFungibleAsset({
assetInfo: {
name: 'Catenis NFA 9',
description: 'Non-fungible asset #9 for testing',
canReissue: true
},
encryptNFTContents: true
}, [{
metadata: {
name: 'NFA9 NFT 1',
description: 'First token of Catenis non-fungible asset #9'
},
contents: {
data: 'Contents of first token of Catenis non-fungible asset #9',
encoding: 'utf8'
}
}, {
metadata: {
name: 'NFA9 NFT 2',
description: 'Second token of Catenis non-fungible asset #9'
},
contents: {
data: 'Here is the contents of the second token of Catenis non-fungible asset #9 (part #1)',
encoding: 'utf8'
}
}],
false,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Continuation token:', data.continuationToken);
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
try {
$data = $ctnApiClient->issueNonFungibleAsset([
'assetInfo' => [
'name' => 'Catenis NFA 9',
'description' => 'Non-fungible asset #9 for testing',
'canReissue' => true
],
'encryptNFTContents' => true
], [
[
'metadata' => [
'name' => 'NFA9 NFT 1',
'description' => 'First token of Catenis non-fungible asset #9'
],
'contents' => [
'data' => 'Contents of first token of Catenis non-fungible asset #9',
'encoding' => 'utf8'
]
],
[
'metadata' => [
'name' => 'NFA9 NFT 2',
'description' => 'Second token of Catenis non-fungible asset #9'
],
'contents' => [
'data' => 'Here is the contents of the second token of Catenis non-fungible asset #9 (part #1)',
'encoding' => 'utf8'
]
]
], false);
// Process returned data
echo 'Continuation token: ' . $data->continuationToken . PHP_EOL;
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let result = ctn_client.issue_non_fungible_asset(
NFAssetIssuanceInfoOrContToken::IssuanceInfo(NonFungibleAssetIssuanceInfo {
asset_info: Some(NewNonFungibleAssetInfo {
name: String::from("NFA 9"),
description: Some(String::from("Non-fungible asset #9 for testing")),
can_reissue: true
}),
encrypt_nft_contents: Some(true),
holding_devices: None,
async_: None,
}),
Some(vec![
Some(NewNonFungibleTokenInfo {
metadata: Some(NewNonFungibleTokenMetadata {
name: String::from("NFA9 NFT 1"),
description: Some(String::from("First token of non-fungible asset #9")),
custom: None,
}),
contents: Some(NewNonFungibleTokenContents {
data: String::from("Contents of first token of non-fungible asset #9"),
encoding: Encoding::UTF8
}),
}),
Some(NewNonFungibleTokenInfo {
metadata: Some(NewNonFungibleTokenMetadata {
name: String::from("NFA9 NFT 2"),
description: Some(String::from("Second token of non-fungible asset #9")),
custom: None,
}),
contents: Some(NewNonFungibleTokenContents {
data: String::from("Here is the contents of the second token of Catenis non-fungible asset #9 (part #1)"),
encoding: Encoding::UTF8
}),
}),
]),
Some(false)
)?;
println!("Continuation token: {}", result.continuation_token.unwrap());
Ok(())
}
Sample request (final continuation call):
POST /api/0.13/assets/non-fungible/issue HTTP/1.1
X-BCoT-Timestamp: 20220816T184627Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220816/ctn1_request, Signature=d320bfba65c206022138f9d3ac2d63fd6058c44b3a01e5462b93522fe3337e19
Content-Type: application/json; charset=utf-8
Host: localhost:3000
Connection: close
User-Agent: Paw/3.3.6 (Macintosh; OS X/12.5.0) GCDHTTPRequest
Content-Length: 226
{"continuationToken":"bRQDsLZpksdHyMPxFk3J","nonFungibleTokens":[null,{"contents":{"data":"; and here is the last part of the contents of the second token of Catenis non-fungible asset #9.","encoding":"utf8"}}],"isFinal":true}
curl -X "POST" "http://localhost:3000/api/0.13/assets/non-fungible/issue" \
-H 'X-BCoT-Timestamp: 20220816T184627Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220816/ctn1_request, Signature=d320bfba65c206022138f9d3ac2d63fd6058c44b3a01e5462b93522fe3337e19' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"continuationToken": "bRQDsLZpksdHyMPxFk3J",
"nonFungibleTokens": [
null,
{
"contents": {
"data": "; and here is the last part of the contents of the second token of Catenis non-fungible asset #9.",
"encoding": "utf8"
}
}
],
"isFinal": true,
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var continuationToken = 'bRQDsLZpksdHyMPxFk3J';
ctnApiClient.issueNonFungibleAsset(continuationToken, [
null, {
contents: {
data: '; and here is the last part of the contents of the second token of Catenis non-fungible asset #9.',
encoding: 'utf8'
}
}],
true,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('ID of newly created non-fungible asset:', data.assetId);
console.log('IDs of newly issued non-fungible tokens:', data.nfTokenIds);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var continuationToken = 'bRQDsLZpksdHyMPxFk3J';
ctnApiClient.issueNonFungibleAsset(continuationToken, [
null, {
contents: {
data: '; and here is the last part of the contents of the second token of Catenis non-fungible asset #9.',
encoding: 'utf8'
}
}],
true,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('ID of newly created non-fungible asset:', data.assetId);
console.log('IDs of newly issued non-fungible tokens:', data.nfTokenIds);
}
});
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$continuationToken = 'bRQDsLZpksdHyMPxFk3J';
try {
$data = $ctnApiClient->issueNonFungibleAsset($continuationToken, [
null,
[
'contents' => [
'data' => '; and here is the last part of the contents of the second token of Catenis non-fungible asset #9.',
'encoding' => 'utf8'
]
]
], true);
// Process returned data
echo 'ID of newly created non-fungible asset: ' . $data->assetId . PHP_EOL;
echo 'IDs of newly issued non-fungible tokens: ' . implode(', ', $data->nfTokenIds) . PHP_EOL;
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let continuation_token = "bRQDsLZpksdHyMPxFk3J";
let result = ctn_client.issue_non_fungible_asset(
NFAssetIssuanceInfoOrContToken::ContinuationToken(String::from(continuation_token)),
Some(vec![
None,
Some(NewNonFungibleTokenInfo {
metadata: None,
contents: Some(NewNonFungibleTokenContents {
data: String::from("; and here is the last part of the contents of the second token of Catenis non-fungible asset #9."),
encoding: Encoding::UTF8
}),
}),
]),
Some(true)
)?;
println!("ID of newly created non-fungible asset: {}", result.asset_id.unwrap());
println!("IDs of newly issued non-fungible tokens: {:?}", result.nf_token_ids.unwrap());
Ok(())
}
Accessibility
Private
Request
POST /assets/non-fungible/issue
Parameters
- Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
assetInfo |
Object | (optional; should be omitted in a continuation call) The properties of the new non-fungible asset to create. |
name |
String | The name of the non-fungible asset. |
description |
String | (optional) A description of the non-fungible asset. |
canReissue |
Boolean | Indicates whether more non-fungible tokens of that non-fungible asset can be issued at a later time. |
encryptNFTContents |
Boolean | (optional, default: true ; should be omitted in a continuation call) Indicates whether the contents of the non-fungible tokens being issued should be encrypted before being stored. |
holdingDevices |
Object|Array(Object) | (optional; should be omitted in a continuation call) A single virtual device or a list of virtual devices that will hold the issued non-fungible tokens. |
id |
String | The ID of the holding device. Should be a device ID unless isProdUniqueId is set. |
isProdUniqueId |
Boolean | (optional, default: false ) Indicates whether the supplied ID is a product unique ID. |
async |
Boolean | (optional, default: false ; should be omitted in a continuation call) Indicates whether processing should be done asynchronously. |
continuationToken |
String | (optional; should be included only in a continuation call) This signals a continuation call of the asset issuance. It should be filled with the continuation token returned by the previous call. |
nonFungibleTokens |
Array(Object) | (optional; may be omitted in the final continuation call) List with the properties of the non-fungible tokens to be issued. |
metadata |
Object | (optional; should be omitted in a continuation call) The properties of the non-fungible token to issue. |
name |
String | The name of the non-fungible token. |
description |
String | (optional) A description of the non-fungible token. |
custom |
Object | (optional) User defined, custom properties of the non-fungible token. |
sensitiveProps |
Object | (optional) User defined, sensitive properties of the non-fungible token. Sensitive properties are encrypted before being stored. |
<prop_name> |
* | A custom, sensitive property identified by prop_name . |
<prop_name> |
* | A custom property identified by prop_name . |
contents |
Object | (optional; may be omitted in the initial call) The contents of the non-fungible token to issue. |
data |
String | An additional chunk of data of the non-fungible token's contents. |
encoding |
String | (optional, default: base64 ) The encoding of the contents data chunk. Valid options: utf8 , base64 , hex . |
isFinal |
Boolean | (optional, default: true ) Indicates whether this is the final call of the asset issuance. There should be no more continuation calls after this is set. |
Sample response (non-final call):
{
"status": "success",
"data": {
"continuationToken": "bRQDsLZpksdHyMPxFk3J"
}
}
Sample response (final call, no asynchronous processing):
{
"status": "success",
"data": {
"assetId": "ahfTzqgWAXnMR6Z57mcp",
"nfTokenIds": [
"tSWtJurhbkSJLGjjbN4R",
"t76Yzrbqcjbtehk6Wecf"
]
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
continuationToken |
String | (only returned for a non-final call) The continuation token to be used in the next continuation call. |
assetIssuanceId |
String | (only returned for a final call when doing processing asynchronously) The asset issuance ID. Used for retrieving the progress of an asynchronous non-fungible asset issuance. |
assetId |
String | (only returned for a final call when not doing processing asynchronously) The ID of the newly created non-fungible asset. |
nfTokenIds |
Array(String) | (only returned for a final call when not doing processing asynchronously) A list of the IDs of the issued non-fungible tokens. |
Possible errors
List Asset Holders
Retrieves a list of virtual devices that currently hold any amount of a given asset.
Sample request:
GET /api/0.13/assets/aQjlzShmrnEZeeYBZihc/holders?limit=200 HTTP/1.1
X-BCoT-Timestamp: 20180417T193524Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=2a5d3aa86d303ed552b408356ae30174f428fab8c377c1f203812ad0b036cfa4
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/assets/aQjlzShmrnEZeeYBZihc/holders?limit=200" \
-H 'X-BCoT-Timestamp: 20180417T193542Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=57ba39226a41800f13f7c985aa6f1ccca98ce6817c15680090e9e18a0ade7e0b'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aQjlzShmrnEZeeYBZihc';
ctnApiClient.listAssetHolders(assetId, 200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
data.assetHolders.forEach(function (assetHolder, idx) {
if (assetHolder.holder) {
console.log('Asset holder #', idx + 1, ':');
console.log(' - device holding an amount of the asset:', assetHolder.holder);
console.log(' - amount of asset currently held by device:', assetHolder.balance.total);
console.log(' - amount not yet confirmed:', assetHolder.balance.unconfirmed);
}
else {
console.log('Migrated asset:');
console.log(' - total migrated amount:', assetHolder.balance.total);
console.log(' - amount not yet confirmed:', assetHolder.balance.unconfirmed);
}
});
if (data.hasMore) {
console.log('Not all asset holders have been returned');
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aQjlzShmrnEZeeYBZihc';
ctnApiClient.listAssetHolders(assetId, 200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
data.assetHolders.forEach(function (assetHolder, idx) {
if (assetHolder.holder) {
console.log('Asset holder #', idx + 1, ':');
console.log(' - device holding an amount of the asset:', assetHolder.holder);
console.log(' - amount of asset currently held by device:', assetHolder.balance.total);
console.log(' - amount not yet confirmed:', assetHolder.balance.unconfirmed);
}
else {
console.log('Migrated asset:');
console.log(' - total migrated amount:', assetHolder.balance.total);
console.log(' - amount not yet confirmed:', assetHolder.balance.unconfirmed);
}
});
if (data.hasMore) {
console.log('Not all asset holders have been returned');
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$assetId = 'aQjlzShmrnEZeeYBZihc';
try {
$data = $ctnApiClient->listAssetHolders($assetId, 200, 0);
// Process returned data
forEach($data->assetHolders as $idx => $assetHolder) {
if (isset($assetHolder->holder)) {
echo 'Asset holder #' . ($idx + 1) . ':' . PHP_EOL;
echo ' - device holding an amount of the asset: ' . print_r($assetHolder->holder, true);
echo ' - amount of asset currently held by device: ' . $assetHolder->balance->total . PHP_EOL;
echo ' - amount not yet confirmed: ' . $assetHolder->balance->unconfirmed . PHP_EOL;
} else {
echo 'Migrated asset:' . PHP_EOL;
echo ' - total migrated amount: ' . $assetHolder->balance->total . PHP_EOL;
echo ' - amount not yet confirmed: ' . $assetHolder->balance->unconfirmed . PHP_EOL;
}
}
if ($data->hasMore) {
echo 'Not all asset holders have been returned' . PHP_EOL;
}
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let asset_id = "aQjlzShmrnEZeeYBZihc";
let result = ctn_client.list_asset_holders(
asset_id,
Some(200),
Some(0),
)?;
for idx in 0..result.asset_holders.len() {
let asset_holder = &result.asset_holders[idx];
if let Some(holder) = &asset_holder.holder {
println!("Asset holder #{}:", idx + 1);
println!(" - device holding an amount of the asset: {:?}", holder);
println!(" - amount of asset currently held by device: {}", asset_holder.balance.total);
println!(" - amount not yet confirmed: {}", asset_holder.balance.unconfirmed);
} else {
println!("Migrated asset:");
println!(" - total migrated amount: {}", asset_holder.balance.total);
println!(" - amount not yet confirmed: {}", asset_holder.balance.unconfirmed);
}
}
if result.has_more {
println!("Not all asset holders have been returned");
}
Ok(())
}
Accessibility
Private
Request
GET /assets/:assetId
/holders
Parameters
- URL parameters:
assetId
: The ID of the asset to get holders.
- Query string parameters:
limit
: (optional, default:500
) Maximum number of list items that should be returned. Must be a positive integer value not greater than 500.skip
: (optional, default:0
) Number of list items that should be skipped (from beginning of list) and not returned. Must be a non-negative (includes zero) integer value.
Sample response:
{
"status": "success",
"data": {
"assetHolders": [
{
"holder": {
"deviceId": "dnN3Ea43bhMTHtTvpytS",
"name": "deviceB",
"prodUniqueId": "XYZABC001"
},
"balance": {
"total": 1145.75,
"unconfirmed": 0
}
},
{
"holder": {
"deviceId": "dv3htgvK7hjnKx3617Re",
"name": "Catenis device #1"
},
"balance": {
"total": 504.25,
"unconfirmed": 0
}
},
{
"migrated": true,
"balance": {
"total": 50,
"unconfirmed": 0
}
}
],
"hasMore": false
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
assetHolders |
Array(Object) | The list of asset holder entries returned. |
holder |
Object | (not returned for the special entry reporting the migrated asset amount) The virtual device that holds an amount of the asset — the holding device. |
deviceId |
String | The device ID of the holding device. |
name |
String | (only returned if holding device has this data, and the virtual device issuing the request has the necessary permission right) The name of the holding device. |
prodUniqueId |
String | (only returned if holding device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the holding device. |
migrated |
Boolean | (only returned for the special entry reporting the migrated asset amount) The value true indicating that this is the special entry reporting the migrated asset amount. |
balance |
Object | |
total |
Number | The current balance of the asset held by this holding device or that had been migrated. |
unconfirmed |
Number | The amount from the balance that is not yet confirmed. |
hasMore |
Boolean | Indicates whether there are more entries that have not been included in the returned list. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid asset ID Invalid parameters: <param_list> |
403 | No permission to list asset holders |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
List Asset Migrations
Retrieves a list of issued asset migrations that satisfy a given search criteria.
Sample request:
GET /api/0.13/assets/migrations?foreignBlockchain=ethereum&direction=outward&status=success&startDate=2021-08-01T00:00:00Z&limit=200&skip=0 HTTP/1.1
X-BCoT-Timestamp: 20210811T142016Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20210811/ctn1_request, Signature=100242f637f3230f54e94dfcc30f25af4abbdf5c34add071130da94d37574379
Host: localhost:3000
Connection: close
User-Agent: Paw/3.2.4 (Macintosh; OS X/11.5.0) GCDHTTPRequest
curl "http://localhost:3000/api/0.13/assets/migrations?foreignBlockchain=ethereum&direction=outward&status=success&startDate=2021-08-01T00:00:00Z&limit=200&skip=0" \
-H 'X-BCoT-Timestamp: 20210811T142047Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20210811/ctn1_request, Signature=418fa567d70d0d8ae0ea38a1bdf068362a8cbfe8ce4c3ecb15f028ea5506169e'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listAssetMigrations({
foreignBlockchain: 'ethereum',
direction: 'outward',
status: 'success',
startDate: new Date('2021-08-01')
}, 200, 0, function (error, data) {
if (error) {
// Process error
}
else {
// Process returned data
if (data.assetMigrations.length > 0) {
console.log('Returned asset migrations:', data.assetMigrations);
if (data.hasMore) {
console.log('Not all asset migrations have been returned');
}
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listAssetMigrations({
foreignBlockchain: 'ethereum',
direction: 'outward',
status: 'success',
startDate: new Date('2021-08-01')
}, 200, 0, function (error, data) {
if (error) {
// Process error
}
else {
// Process returned data
if (data.assetMigrations.length > 0) {
console.log('Returned asset migrations:', data.assetMigrations);
if (data.hasMore) {
console.log('Not all asset migrations have been returned');
}
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
try {
$data = $ctnApiClient->listAssetMigrations([
'foreignBlockchain' => 'ethereum',
'direction' => 'outward',
'status' => 'success',
'startDate' => new \DateTime('20210801T000000Z')
], 200, 0);
// Process returned data
if (count($data->assetMigrations) > 0) {
echo 'Returned asset migrations: ' . print_r($data->assetMigrations, true);
if ($data->hasMore) {
echo 'Not all asset migrations have been returned' . PHP_EOL;
}
}
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let result = ctn_client.list_asset_migrations(
Some(ListAssetMigrationsOptions {
asset_id: None,
foreign_blockchain: Some(ForeignBlockchain::Ethereum),
direction: Some(AssetMigrationDirection::Outward),
status: Some(vec![AssetMigrationStatus::Success]),
negate_status: None,
start_date: Some("2021-08-01T00:00:00Z".into()),
end_date: None,
limit: Some(200),
skip: Some(0),
}),
)?;
if result.asset_migrations.len() > 0 {
println!("Returned asset migrations: {:?}", result.asset_migrations);
if result.has_more {
println!("Not all asset migrations have been returned");
}
}
Ok(())
}
Accessibility
Private
Request
GET /assets/migrations
Parameters
- Query string parameters:
assetId
: (optional) The ID of the asset the amount of which has been migrated.foreignBlockchain
: (optional) The key identifying the foreign blockchain to/from where the asset amount has been migrated. Valid options:ethereum
,binance
,polygon
.direction
: (optional) The direction of the migration. Valid options:outward
,inward
.status
: (optional) A single status or a comma-separated list of statuses to include. Valid options:pending
,interrupted
,success
,error
.negateStatus
: (optional, default:false
) Boolean value indicating whether the specified statuses should be excluded instead.startDate
: (optional) ISO 8601 formatted date and time specifying the inclusive lower bound of the time frame within which the asset amount has been migrated.endDate
: (optional) ISO 8601 formatted date and time specifying the inclusive upper bound of the time frame within which the asset amount has been migrated.limit
: (optional, default:500
) Maximum number of asset migrations that should be returned. Must be a positive integer value not greater than 500.skip
: (optional, default:0
) Number of asset migrations that should be skipped (from beginning of list of matching asset migrations) and not returned. Must be a non-negative (includes zero) integer value.
Sample response:
{
"status": "success",
"data": {
"assetMigrations": [
{
"migrationId": "gSLb9FTdGxgSLufuNzhR",
"assetId": "aH2AkrrL55GcThhPNa3J",
"foreignBlockchain": "ethereum",
"direction": "inward",
"amount": 4,
"catenisService": {
"status": "fulfilled",
"txid": "26d45a275447caf36e0fbcc32f880f37d3aadb37ddceccc39cd8972a7933e3f4"
},
"foreignTransaction": {
"txid": "0x883a4d9e02713b177fdd26b33e871dc765db3c964f2b1ef8e6f97eca24d718ee",
"isPending": false,
"success": true
},
"status": "success",
"date": "2021-08-03T19:11:27.804Z"
},
{
"migrationId": "gTQ8Qf5W6kdmdYdEEoD9",
"assetId": "aCSy24HLjKMbpnvJ8GTx",
"foreignBlockchain": "ethereum",
"direction": "outward",
"amount": 5,
"catenisService": {
"status": "fulfilled",
"txid": "7d6a20ee009ad2bcbf5c799ee4eac594e4447bdb5007250f8ba038de97f63777"
},
"foreignTransaction": {
"txid": "0x92fb47432e50b623441bb3b55dd65bf879183f87ea4913a16e75503c98792df9",
"isPending": false,
"success": true
},
"status": "success",
"date": "2021-08-10T13:00:08.656Z"
}
],
"hasMore": false
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
assetMigrations |
Array(Object) | The returned list of issued asset migrations that satisfy the search criteria. The list is sorted in ascending order in regard to the returned date field. |
migrationId |
String | The ID of the asset migration. |
assetId |
String | The ID of the asset the amount of which has been migrated. |
foreignBlockchain |
String | The key identifying the foreign blockchain to/from where the asset amount has been migrated. One of: ethereum , binance , or polygon . |
direction |
String | The direction of the migration. One of: outward or inward . |
amount |
Number | The migrated asset amount. |
catenisService |
Object | Information about the execution of the migrate asset Catenis service. |
status |
String | The current state of the service's execution. One of: awaiting , failure , or fulfilled . |
txid |
String | (only returned if the service is successfully fulfilled) The ID of the Catenis transaction issued to fulfill the service. |
error |
String | (only returned if the service's execution has failed) An error message describing what went wrong when executing the service. |
foreignTransaction |
Object | Information about the transaction issued on the foreign blockchain to mint/burn the amount of the foreign token. |
txid |
String | The ID (or hash) of the foreign blockchain transaction. |
isPending |
Boolean | Indicates whether the foreign blockchain transaction is yet to be executed. |
success |
Boolean | Indicates whether the foreign blockchain transaction has been successfully executed or not. |
error |
String | (only returned if the foreign blockchain transaction's execution has failed) An error message describing what went wrong when executing the transaction. |
status |
String | The current state of the asset migration. One of: pending , interrupted , success , or error . |
date |
String | ISO 8601 formatted date and time when the asset amount has been migrated. |
hasMore |
Boolean | Indicates whether there are more asset migrations that satisfy the search criteria yet to be returned. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid parameters: <param_list> |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
List Exported Assets
Retrieves a list of issued asset exports that satisfy a given search criteria.
Sample request:
GET /api/0.13/assets/exported?foreignBlockchain=ethereum&status=success&startDate=2021-08-01T00:00:00Z&limit=200&skip=0 HTTP/1.1
X-BCoT-Timestamp: 20210811T115512Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20210811/ctn1_request, Signature=34abef10e2e75e8a3c2f66f1b40d50a2cb2e6f88ff7baff8e8fbd983a29d1c4b
Host: localhost:3000
Connection: close
User-Agent: Paw/3.2.3 (Macintosh; OS X/11.5.0) GCDHTTPRequest
curl "http://localhost:3000/api/0.13/assets/exported?foreignBlockchain=ethereum&status=success&startDate=2021-08-01T00:00:00Z&limit=200&skip=0" \
-H 'X-BCoT-Timestamp: 20210811T115534Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20210811/ctn1_request, Signature=258e511f7272407ba344922c0d68a63388018e70bcc2885acf343c415f0caf36'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listExportedAssets({
foreignBlockchain: 'ethereum',
status: 'success',
startDate: new Date('2021-08-01')
}, 200, 0, function (error, data) {
if (error) {
// Process error
}
else {
// Process returned data
if (data.exportedAssets.length > 0) {
console.log('Returned asset exports:', data.exportedAssets);
if (data.hasMore) {
console.log('Not all asset exports have been returned');
}
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listExportedAssets({
foreignBlockchain: 'ethereum',
status: 'success',
startDate: new Date('2021-08-01')
}, 200, 0, function (error, data) {
if (error) {
// Process error
}
else {
// Process returned data
if (data.exportedAssets.length > 0) {
console.log('Returned asset exports:', data.exportedAssets);
if (data.hasMore) {
console.log('Not all asset exports have been returned');
}
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
try {
$data = $ctnApiClient->listExportedAssets([
'foreignBlockchain' => 'ethereum',
'status' => 'success',
'startDate' => new \DateTime('20210801T000000Z')
], 200, 0);
// Process returned data
if (count($data->exportedAssets) > 0) {
echo 'Returned asset exports: ' . print_r($data->exportedAssets, true);
if ($data->hasMore) {
echo 'Not all asset exports have been returned' . PHP_EOL;
}
}
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let result = ctn_client.list_exported_assets(
Some(ListExportedAssetsOptions {
asset_id: None,
foreign_blockchain: Some(ForeignBlockchain::Ethereum),
token_symbol: None,
status: Some(vec![AssetExportStatus::Success]),
negate_status: None,
start_date: Some("2021-08-01T00:00:00Z".into()),
end_date: None,
limit: Some(200),
skip: Some(0),
}),
)?;
if result.exported_assets.len() > 0 {
println!("Returned asset exports: {:?}", result.exported_assets);
if result.has_more {
println!("Not all asset exports have been returned");
}
}
Ok(())
}
Accessibility
Private
Request
GET /assets/exported
Parameters
- Query string parameters:
assetId
: (optional) The ID of the exported asset.foreignBlockchain
: (optional) The key identifying the foreign blockchain to where the asset has been exported. Valid options:ethereum
,binance
,polygon
.tokenSymbol
: (optional) The symbol of the resulting foreign token.status
: (optional) A single status or a comma-separated list of statuses to include. Valid options:pending
,success
,error
.negateStatus
: (optional, default:false
) Boolean value indicating whether the specified statuses should be excluded instead.startDate
: (optional) ISO 8601 formatted date and time specifying the inclusive lower bound of the time frame within which the asset has been exported.endDate
: (optional) ISO 8601 formatted date and time specifying the inclusive upper bound of the time frame within which the asset has been exported.limit
: (optional, default:500
) Maximum number of asset exports that should be returned. Must be a positive integer value not greater than 500.skip
: (optional, default:0
) Number of asset exports that should be skipped (from beginning of list of matching asset exports) and not returned. Must be a non-negative (includes zero) integer value.
Sample response:
{
"status": "success",
"data": {
"exportedAssets": [
{
"assetId": "aH2AkrrL55GcThhPNa3J",
"foreignBlockchain": "ethereum",
"foreignTransaction": {
"txid": "0x1f14474f441557056055a186ccf6839bd4dfce79e0b134d77084b6ef4274dc1a",
"isPending": false,
"success": true
},
"token": {
"name": "Catenis test token #10",
"symbol": "CTK10",
"id": "0x537580164Ba9DB2e8C254a38E254ce15d07fDef9"
},
"status": "success",
"date": "2021-08-03T18:41:27.679Z"
},
{
"assetId": "aCSy24HLjKMbpnvJ8GTx",
"foreignBlockchain": "ethereum",
"foreignTransaction": {
"txid": "0x6299c35ccfa803ab0cb043e8d8ae4be8d7f3432d85f288ebb81e4d624e566b0a",
"isPending": false,
"success": true
},
"token": {
"name": "Catenis test token #11",
"symbol": "CTK11",
"id": "0x5cE78E7204DD8f7d86142fAaA694d5354b997600"
},
"status": "success",
"date": "2021-08-10T12:57:24.217Z"
}
],
"hasMore": false
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
exportedAssets |
Array(Object) | The returned list of issued asset exports that satisfy the search criteria. The list is sorted in ascending order in regard to the returned date field. |
assetId |
String | The ID of the exported asset. |
foreignBlockchain |
String | The key identifying the foreign blockchain to where the asset has been exported. One of: ethereum , binance , or polygon . |
foreignTransaction |
Object | Information about the transaction issued on the foreign blockchain to create the resulting foreign token. |
txid |
String | The ID (or hash) of the foreign blockchain transaction. |
isPending |
Boolean | Indicates whether the foreign blockchain transaction is yet to be executed. |
success |
Boolean | (only returned after the foreign blockchain transaction is executed) Indicates whether the foreign blockchain transaction has been successfully executed or not. |
error |
String | (only returned if the foreign blockchain transaction's execution has failed) An error message describing what went wrong when executing the transaction. |
token |
Object | Information about the resulting foreign token. |
name |
String | The token name. |
symbol |
String | The token symbol. |
id |
String | (only returned if the asset is successfully export) The ID (or address) of the token on the foreign blockchain. |
status |
String | The current state of the asset export. One of: pending , success , or error |
date |
String | ISO 8601 formatted date and time when the asset has been exported. |
hasMore |
Boolean | Indicates whether there are more asset exports that satisfy the search criteria yet to be returned. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid parameters: <param_list> |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
List Issued Assets
Retrieves a list of assets that have been issued by the device.
Sample request:
GET /api/0.13/assets/issued?limit=200 HTTP/1.1
X-BCoT-Timestamp: 20180417T193403Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=ba41de81d939995b7cf76c03a4bc5861bf2176b7622348648c64fbb6f38dbc3a
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/assets/issued?limit=200" \
-H 'X-BCoT-Timestamp: 20180417T193421Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=eb1e37742272ef732dae3d85cd0d75b32731b6d85d20d501d7969d55ca998849'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listIssuedAssets(200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
data.issuedAssets.forEach(function (issuedAsset, idx) {
console.log('Issued asset #', idx + 1, ':');
console.log(' - asset ID:', issuedAsset.assetId);
console.log(' - total existent balance:', issuedAsset.totalExistentBalance);
});
if (data.hasMore) {
console.log('Not all issued assets have been returned');
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listIssuedAssets(200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
data.issuedAssets.forEach(function (issuedAsset, idx) {
console.log('Issued asset #', idx + 1, ':');
console.log(' - asset ID:', issuedAsset.assetId);
console.log(' - total existent balance:', issuedAsset.totalExistentBalance);
});
if (data.hasMore) {
console.log('Not all issued assets have been returned');
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
try {
$data = $ctnApiClient->listIssuedAssets(200, 0);
// Process returned data
forEach($data->issuedAssets as $idx => $issuedAsset) {
echo 'Issued asset #' . ($idx + 1) . ':' . PHP_EOL;
echo ' - asset ID: ' . $issuedAsset->assetId . PHP_EOL;
echo ' - total existent balance: ' . $issuedAsset->totalExistentBalance . PHP_EOL;
}
if ($data->hasMore) {
echo 'Not all issued assets have been returned' . PHP_EOL;
}
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let result = ctn_client.list_issued_assets(
Some(200),
Some(0),
)?;
for idx in 0..result.issued_assets.len() {
let issued_asset = &result.issued_assets[idx];
println!("Issued asset #{}:", idx + 1);
println!(" - asset ID: {}", issued_asset.asset_id);
println!(" - total existent balance: {}", issued_asset.total_existent_balance);
}
if result.has_more {
println!("Not all issued assets have been returned");
}
Ok(())
}
Accessibility
Private
Request
GET /assets/issued
Parameters
- Query string parameters:
limit
: (optional, default:500
) Maximum number of list items that should be returned. Must be a positive integer value not greater than 500.skip
: (optional, default:0
) Number of list items that should be skipped (from beginning of list) and not returned. Must be a non-negative (includes zero) integer value.
Sample response:
{
"status": "success",
"data": {
"issuedAssets": [
{
"assetId": "aQjlzShmrnEZeeYBZihc",
"totalExistentBalance": 1650
}
],
"hasMore": false
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
issuedAssets |
Array(Object) | The list of issued asset entries returned. |
assetId |
String | The ID of the asset. |
totalExistentBalance |
Number | The current total balance of that asset in existence. |
hasMore |
Boolean | Indicates whether there are more entries that have not been included in the returned list. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid parameters: <param_list> |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
List Messages
Retrieves a list of message entries that satisfy a given search criteria.
A virtual device can use it to identify newly received messages, for instance.
Sample request:
GET /api/0.13/messages?action=send&direction=inbound&fromDeviceIds=dv3htgvK7hjnKx3617Re&readState=unread&startDate=2018-01-01T00:00:00Z&endDate=2018-02-28T23:59:59Z&limit=200&skip=0 HTTP/1.1
X-BCoT-Timestamp: 20180216T135036Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180216/ctn1_request, Signature=bb8a7853798df41e6f9af1a900da4c3cecc161265ec85649f8b883678e8993ed
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/messages?action=send&direction=inbound&fromDeviceIds=dv3htgvK7hjnKx3617Re&readState=unread&startDate=2018-01-01T00:00:00Z&endDate=2018-02-28T23:59:59Z&limit=200&skip=0" \
-H 'X-BCoT-Timestamp: 20180216T135101Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180216/ctn1_request, Signature=c0bb81382db103e30859056646bfa17759e9e8f73778abc0245fdbdb54be4656'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listMessages({
action: 'send',
direction: 'inbound',
fromDevices: [{
id: 'dv3htgvK7hjnKx3617Re'
}],
readState: 'unread',
startDate: '20180101T000000Z',
endDate: '20180228T235959Z'
}, 200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
if (data.msgCount > 0) {
console.log('Returned messages:', data.messages);
if (data.hasMore) {
console.log('Not all messages have been returned');
}
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listMessages({
action: 'send',
direction: 'inbound',
fromDevices: [{
id: 'dv3htgvK7hjnKx3617Re'
}],
readState: 'unread',
startDate: '20180101T000000Z',
endDate: '20180228T235959Z'
}, 200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
if (data.msgCount > 0) {
console.log('Returned messages:', data.messages);
if (data.hasMore) {
console.log('Not all messages have been returned');
}
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
try {
$data = $ctnApiClient->listMessages([
'action' => 'send',
'direction' => 'inbound',
'fromDevices' => [[
'id' => 'dv3htgvK7hjnKx3617Re'
]],
'readState' => 'unread',
'startDate' => '20180101T000000Z',
'endDate' => '20180228T235959Z'
], 200, 0);
// Process returned data
if ($data->msgCount > 0) {
echo 'Returned messages: ' . print_r($data->messages, true);
if ($data->hasMore) {
echo 'Not all messages have been returned' . PHP_EOL;
}
}
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let result = ctn_client.list_messages(
Some(ListMessagesOptions {
action: Some(MessageActionOption::Send),
direction: Some(MessageDirectionOption::Inbound),
from_devices: Some(vec![
DeviceId {
id: String::from("dv3htgvK7hjnKx3617Re"),
is_prod_unique_id: None,
},
]),
to_devices: None,
read_state: Some(MessageReadStateOption::Unread),
start_date: Some("2018-01-01T00:00:00Z".into()),
end_date: Some("2018-02-28T23:59:59Z".into()),
limit: Some(200),
skip: Some(0),
}),
)?;
if result.msg_count > 0 {
println!("Returned messages: {:?}", result.messages);
if result.has_more {
println!("Not all messages have been returned");
}
}
Ok(())
}
Accessibility
Private
Request
GET /messages
Parameters
- Query string parameters:
action
: (optional, default:any
) Action originally performed on the messages to be retrieved. Valid options:log
,send
,any
. Uselog
to retrieve only logged messages, andsend
to retrieve only sent messages. The valueany
can be used to retrieve both logged and sent messages.direction
: (optional, default:any
) The direction of the sent messages to be retrieved. Valid options:inbound
,outbound
,any
. Useinbound
to retrieve only sent messages that had been received by the virtual device issuing the request, andoutbound
to retrieve only sent messages that had been sent by the device issuing the request. The valueany
can be used to retrieve both inbound and outbound messages.fromDeviceIds
: (optional) A comma-separated list of virtual device IDs specifying the devices from which the sent messages to be retrieved had been sent. Note that this option only applies to inbound sent messages.fromDeviceProdUniqueIds
: (optional) A comma-separated list of product unique IDs specifying the devices from which the sent messages to be retrieved had been sent. Note that this option only applies to inbound sent messages.toDeviceIds
: (optional) A comma-separated list of virtual device IDs specifying the devices to which the sent messages to be retrieved had been sent. Note that this option only applies to outbound sent messages.toDeviceProdUniqueIds
: (optional) A comma-separated list of product unique IDs specifying the devices to which the sent messages to be retrieved had been sent. Note that this option only applies to outbound sent messages.readState
: (optional, default:any
) The current read state of the message. Valid options:read
,unread
,any
. Useread
to retrieve only logged or inbound sent messages that had already been read by the virtual device issuing the request, or outbound sent messages sent with the read confirmation option set for which a message read notification has already been received. Useunread
to retrieve only logged or inbound sent messages that had not yet been read by the device issuing the request, or outbound sent messages sent with the read confirmation option set for which a message read notification has not been received yet. Useany
if you do not care about the read state of the message to be retrieved.startDate
: (optional) ISO 8601 formatted date and time specifying the inclusive lower bound of the time frame within which the messages to be retrieved had been: logged, for logged messages; sent, for outbound sent messages; and received, for inbound sent messages.endDate
: (optional) ISO 8601 formatted date and time specifying the inclusive upper bound of the time frame within which the messages to be retrieved had been: logged, for logged messages; sent, for outbound sent messages; and received, for inbound sent messages.limit
: (optional, default:500
) Maximum number of messages that should be returned. Must be a positive integer value not greater than 500.skip
: (optional, default:0
) Number of messages that should be skipped (from beginning of list of matching messages) and not returned. Must be a non-negative (includes zero) integer value.
Sample response:
{
"status": "success",
"data": {
"messages": [
{
"messageId": "mospScAtxyX8ytD9Cq58",
"action": "log",
"read": false,
"date": "2018-01-29T23:25:47.865Z"
},
{
"messageId": "mNEWqgSMAeDAmBAkBDWr",
"action": "send",
"direction": "outbound",
"to": {
"deviceId": "dv3htgvK7hjnKx3617Re",
"name": "Catenis device #1"
},
"readConfirmationEnabled": true,
"read": true,
"date": "2018-01-29T23:27:39.331Z"
}
],
"msgCount": 2,
"hasMore": false
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
messages |
Array(Object) | The returned list of message information entries including the messages that satisfy the search criteria. The list is sorted in ascending order in regard to the returned date field. |
messageId |
String | The ID of the message. |
action |
String | Action originally performed on the message. Possible values: log , send . The value log indicates that this is a logged message, and the value send indicates that this is a sent message. |
direction |
String | (only returned for sent messages) The direction of the sent message. Possible values: inbound , outbound . The value inbound indicates that this is a message received by the virtual device issuing the request, and the value outbound indicates that this is a message sent by the device issuing the request. |
from |
Object | (only returned for sent messages) Identifies the virtual device that sent the message — the origin device. |
deviceId |
String | The device ID of the origin device. |
name |
String | (only returned if origin device has this data, and the device issuing the request has the necessary permission right) The name of the origin device. |
prodUniqueId |
String | (only returned if origin device has this data, and the device issuing the request has the necessary permission right) The product unique ID of the origin device. |
to |
Object | (only returned for sent messages) Identifies the device to which the message had been sent — the target device. |
deviceId |
String | The device ID of the target device. |
name |
String | (only returned if target device has this data, and the device issuing the request has the necessary permission right) The name of the target device. |
prodUniqueId |
String | (only returned if target device has this data, and the device issuing the request has the necessary permission right) The product unique ID of the target device. |
readConfirmationEnabled |
Boolean | (only returned for outbound sent messages) Indicates whether message had been sent with read confirmation enabled. |
read |
Boolean | (not returned for outbound sent messages sent with read confirmation not enabled) Indicates whether the message had already been read. |
date |
String | ISO 8601 formatted date and time when the message had been: logged, for logged message; sent, for outbound sent message; and received, for inbound sent message. |
msgCount |
Number | Number of messages for which information was returned. |
hasMore |
Boolean | Indicates whether there are more messages that satisfy the search criteria yet to be returned. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid parameters: <param_list> |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
List Notification Events
Retrieves a list of all system defined notification events.
Sample request:
GET /api/0.13/notification/events HTTP/1.1
X-BCoT-Timestamp: 20180219T160411Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=02e8f56a46e2ea8001f94fac04115749606deacd5eee6f553b6d69c5d45ce553
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/notification/events" \
-H 'X-BCoT-Timestamp: 20180219T160346Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=7b717edae1c2c60721e2f74d02feb286a2275f615c930d86f5ea9954214bdfaf'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listNotificationEvents(function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
Object.keys(data).forEach(function (eventName) {
console.log('Event name:', eventName, '; event description:', data[eventName]);
});
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listNotificationEvents(function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
Object.keys(data).forEach(function (eventName) {
console.log('Event name:', eventName, '; event description:', data[eventName]);
});
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
try {
$data = $ctnApiClient->listNotificationEvents();
// Process returned data
forEach($data as $eventName => $description) {
echo 'Event name: ' . $eventName . '; event description: ' . $description . PHP_EOL;
}
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let result = ctn_client.list_notification_events()?;
for (event, description) in result {
println!("Event name: {}; event description: {}", event.to_string(), description);
}
Ok(())
}
Accessibility
Private
Request
GET /notification/events
Parameters
This request does not take any parameters.
Sample response:
{
"status": "success",
"data": {
"new-msg-received": "A new message has been received",
"sent-msg-read": "Previously sent message has been read by intended receiver (target device)",
"asset-received": "An amount of an asset has been received",
"asset-confirmed": "An amount of an asset that was pending due to an asset transfer has been confirmed",
"final-msg-progress": "Progress of asynchronous message processing has come to an end",
"asset-export-outcome": "Asset export has been finalized",
"asset-migration-outcome": "Asset migration has been finalized",
"nf-token-received": "One or more non-fungible tokens have been received",
"nf-token-confirmed": "One or more non-fungible tokens that were pending due to a non-fungible token issuance/transfer has been confirmed",
"nf-asset-issuance-outcome": "Non-fungible asset issuance has been finalized",
"nf-token-retrieval-outcome": "Non-fungible token retrieval has been finalized",
"nf-token-transfer-outcome": "Non-fungible token transfer has been finalized"
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. In this particular case, it is an object that works as a dictionary where its properties are the notification event names, and their respective values the notification event description. |
<event_name> |
String | The description of the notification event whose name is this property's name. |
Possible errors
Status code | Error message |
---|---|
500 | Internal server error |
503 | System currently not available; please try again at a later time |
List Owned Assets
Retrieves a list of assets that are currently held by the device.
Sample request:
GET /api/0.13/assets/owned?limit=200 HTTP/1.1
X-BCoT-Timestamp: 20180417T193253Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=e1986d68550fe45536e407ec0eba3d0104579106f3486b9aec652ac0f78add43
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/assets/owned?limit=200" \
-H 'X-BCoT-Timestamp: 20180417T193325Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=2c6c8a066e7e983ad059854a3209ae7cfd024f1be504d51b5939fc3780dce8ae'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listOwnedAssets(200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
data.ownedAssets.forEach(function (ownedAsset, idx) {
console.log('Owned asset #', idx + 1, ':');
console.log(' - asset ID:', ownedAsset.assetId);
console.log(' - current asset balance:', ownedAsset.balance.total);
console.log(' - amount not yet confirmed:', ownedAsset.balance.unconfirmed);
});
if (data.hasMore) {
console.log('Not all owned assets have been returned');
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listOwnedAssets(200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
data.ownedAssets.forEach(function (ownedAsset, idx) {
console.log('Owned asset #', idx + 1, ':');
console.log(' - asset ID:', ownedAsset.assetId);
console.log(' - current asset balance:', ownedAsset.balance.total);
console.log(' - amount not yet confirmed:', ownedAsset.balance.unconfirmed);
});
if (data.hasMore) {
console.log('Not all owned assets have been returned');
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
try {
$data = $ctnApiClient->listOwnedAssets(200, 0);
// Process returned data
foreach ($data->ownedAssets as $idx => $ownedAsset) {
echo 'Owned asset #' . ($idx + 1) . ':' . PHP_EOL;
echo ' - asset ID: ' . $ownedAsset->assetId . PHP_EOL;
echo ' - current asset balance: ' . $ownedAsset->balance->total . PHP_EOL;
echo ' - amount not yet confirmed: ' . $ownedAsset->balance->unconfirmed . PHP_EOL;
}
if ($data->hasMore) {
echo 'Not all owned assets have been returned' . PHP_EOL;
}
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let result = ctn_client.list_owned_assets(
Some(200),
Some(0),
)?;
for idx in 0..result.owned_assets.len() {
let owned_asset = &result.owned_assets[idx];
println!("Owned asset #{}:", idx + 1);
println!(" - asset ID: {}", owned_asset.asset_id);
println!(" - current asset balance: {}", owned_asset.balance.total);
println!(" - amount not yet confirmed: {}", owned_asset.balance.unconfirmed);
}
if result.has_more {
println!("Not all owned assets have been returned");
}
Ok(())
}
Accessibility
Private
Request
GET /assets/owned
Parameters
- Query string parameters:
limit
: (optional, default:500
) Maximum number of list items that should be returned. Must be a positive integer value not greater than 500.skip
: (optional, default:0
) Number of list items that should be skipped (from beginning of list) and not returned. Must be a non-negative (includes zero) integer value.
Sample response:
{
"status": "success",
"data": {
"ownedAssets": [
{
"assetId": "aQjlzShmrnEZeeYBZihc",
"balance": {
"total": 1145.75,
"unconfirmed": 0
}
},
{
"assetId": "asEKmm6pdJomwmajghDy",
"balance": {
"total": 300000,
"unconfirmed": 0
}
}
],
"hasMore": false
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
ownedAssets |
Array(Object) | The list of owned asset entries returned. |
assetId |
String | The ID of the asset. |
balance |
Object | |
total |
Number | The current balance of that asset held by the device that issues the request. |
unconfirmed |
Number | The amount from the balance that is not yet confirmed. |
hasMore |
Boolean | Indicates whether there are more entries that have not been included in the returned list. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid parameters: <param_list> |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
List Owned Non-Fungible Tokens
Retrieve a list of the non-fungible tokens of a given non-fungible asset that are currently owned by the virtual device issuing the request.
Sample request:
GET /api/0.13/assets/non-fungible/aiqXDyh7hhukwxFhR69x/tokens/owned?limit=200 HTTP/1.1
X-BCoT-Timestamp: 20221122T182951Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20221122/ctn1_request, Signature=912d31a2288ccf6805736f85eb938779de346e8ab17a61493e04d240d5f1daca
Host: localhost:3000
Connection: close
User-Agent: RapidAPI/4.0.0 (Macintosh; OS X/13.0.1) GCDHTTPRequest
curl "http://localhost:3000/api/0.13/assets/non-fungible/aiqXDyh7hhukwxFhR69x/tokens/owned?limit=200" \
-H 'X-BCoT-Timestamp: 20221122T183009Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20221122/ctn1_request, Signature=b8b005834cc420892664b393d6255f459e9eac3470190923addbc06692951a82'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aiqXDyh7hhukwxFhR69x';
ctnApiClient.listOwnedNonFungibleTokens(assetId, 200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Owned non-fungible tokens:', data.ownedNFTokens);
if (data.hasMore) {
console.log('Not all owned non-fungible tokens have been returned');
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'ahfTzqgWAXnMR6Z57mcp';
ctnApiClient.listOwnedNonFungibleTokens(assetId, 200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Owned non-fungible tokens:', data.ownedNFTokens);
if (data.hasMore) {
console.log('Not all owned non-fungible tokens have been returned');
}
}
});
Accessibility
Private
Request
GET assets/non-fungible/:assetId
/tokens/owned
Parameters
URL parameters:
assetId
: The ID of the non-fungible asset the non-fungible tokens of which that are currently owned by the virtual device issuing the request should be retrieved.
Query string parameters:
limit
: (optional, default:500
) A numeric value representing the maximum number of list items that should be returned. Must be a positive integer value not greater than 500.skip
: (optional, default:0
) A numeric value representing the number of list items that should be skipped (from beginning of list) and not returned. Must be a non-negative (includes zero) integer value.
Sample response:
{
"status": "success",
"data": {
"ownedNFTokens": [
{
"tokenId": "tN2ax6ebWQLr6ECRuoyS",
"isConfirmed": true
},
{
"tokenId": "twy3fNwmZjkRaawcMpmP",
"isConfirmed": true
},
{
"tokenId": "tWFsWnaxQa6kHz5Wcqkw",
"isConfirmed": true
},
{
"tokenId": "t45bMckekRanrZnTYGsw",
"isConfirmed": true
}
],
"hasMore": false
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
ownedNFTokens |
Array(Object) | The returned list of owned non-fungible tokens. |
tokenId |
String | The ID of the non-fungible token. |
isConfirmed |
Boolean | Indicates whether the blockchain transaction used to transfer the non-fungible token has already been confirmed. |
hasMore |
Boolean | Indicates whether there are more entries that have not been included in the returned list. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid asset ID Invalid parameters: <param_list> Not a non-fungible asset |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
List Permission Events
Retrieves a list of all system defined permission events.
Sample request:
GET /api/0.13/permission/events HTTP/1.1
X-BCoT-Timestamp: 20180217T165054Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=138e50e836dec8c78d48a46bd04c03434ff994b2cf59d929dff324e958f2c096
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/permission/events" \
-H 'X-BCoT-Timestamp: 20180217T170003Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=d1f7556572b5f038563e997644a9682690c87fab6388ccbb16221ab4b72b3a56'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listPermissionEvents(function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
Object.keys(data).forEach(function (eventName) {
console.log('Event name:', eventName, '; event description:', data[eventName]);
});
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.listPermissionEvents(function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
Object.keys(data).forEach(function (eventName) {
console.log('Event name:', eventName, '; event description:', data[eventName]);
});
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
try {
$data = $ctnApiClient->listPermissionEvents();
// Process returned data
forEach($data as $eventName => $description) {
echo 'Event name: ' . $eventName . '; event description: ' . $description . PHP_EOL;
}
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let result = ctn_client.list_permission_events()?;
for (event, description) in result {
println!("Event name: {}; event description: {}", event.to_string(), description);
}
Ok(())
}
Accessibility
Private
Request
GET /permission/events
Parameters
This request does not take any parameters.
Sample response:
{
"status": "success",
"data": {
"receive-notify-new-msg": "Receive notification of new message from a device",
"receive-notify-msg-read": "Receive notification of message read by a device",
"receive-notify-asset-of": "Receive notification of asset received for assets issued by a device",
"receive-notify-asset-from": "Receive notification of asset received from a device",
"receive-notify-confirm-asset-of": "Receive notification of confirmation of pending asset issued by a device",
"receive-notify-confirm-asset-from": "Receive notification of confirmation of pending asset transferred by a device",
"receive-notify-nf-token-of": "Receive notification of non-fungible token received for non-fungible tokens issued by a device",
"receive-notify-nf-token-from": "Receive notification of non-fungible token received from a device",
"receive-notify-confirm-nf-token-of": "Receive notification of confirmation of pending non-fungible token issued by a device",
"receive-notify-confirm-nf-token-from": "Receive notification of confirmation of pending non-fungible token transferred by a device",
"send-read-msg-confirm": "Send read message confirmation to a device",
"receive-msg": "Receive message from a device",
"disclose-main-props": "Disclose device's main properties (name, product unique ID) to a device",
"disclose-identity-info": "Disclose device's basic identification information to a device",
"receive-asset-of": "Receive an amount of an asset issued by a device",
"receive-asset-from": "Receive an amount of an asset from a device",
"receive-nf-token-of": "Receive a non-fungible token issued by a device",
"receive-nf-token-from": "Receive a non-fungible token from a device",
"disclose-nf-token-ownership": "Disclose device's non-fungible token ownership status to a device"
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. In this particular case, it is an object that works as a dictionary where its properties are the permission event names, and their respective values the permission event description. |
<event_name> |
String | The description of the permission event whose name is this property's name. |
Possible errors
Status code | Error message |
---|---|
500 | Internal server error |
503 | System currently not available; please try again at a later time |
Log Message
Records a message on the blockchain.
Sample request:
POST /api/0.13/messages/log HTTP/1.1
X-BCoT-Timestamp: 20200122T195904Z
Authorization: CTN1-HMAC-SHA256 Credential=d8YpQ7jgPBJEkBrnvp58/20200122/ctn1_request, Signature=867604b6d15575907e6c40ca8ef5f5d07c4791eed1a7a6a0fc358cd5d850948a
Content-Type: application/json; charset=utf-8
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.10 (Macintosh; OS X/10.15.2) GCDHTTPRequest
Content-Length: 111
{"message":"This is only a test","options":{"encoding":"utf8","encrypt":true,"offChain":true,"storage":"auto"}}
curl -X "POST" "http://localhost:3000/api/0.13/messages/log" \
-H 'X-BCoT-Timestamp: 20200122T195936Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=d8YpQ7jgPBJEkBrnvp58/20200122/ctn1_request, Signature=a68ef08c0f45b23a557440cc505380b30c1850828c75b8a96d351d129d3022db' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"message": "This is only a test",
"options": {
"encoding": "utf8",
"encrypt": true,
"offChain": true,
"storage": "auto"
}
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.logMessage('This is only a test', {
encoding: 'utf8',
encrypt: true,
offChain: true,
storage: 'auto'
},
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('ID of logged message:', data.messageId);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.logMessage('This is only a test', {
encoding: 'utf8',
encrypt: true,
offChain: true,
storage: 'auto'
},
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('ID of logged message:', data.messageId);
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
try {
$data = $ctnApiClient->logMessage('This is only a test', [
'encoding' => 'utf8',
'encrypt' => true,
'offChain' => true,
'storage' => 'auto'
]);
// Process returned data
echo 'ID of logged message: ' . $data->messageId . PHP_EOL;
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let result = ctn_client.log_message(
Message::Whole(String::from("This is only a test")),
Some(LogMessageOptions {
encoding: Some(Encoding::UTF8),
encrypt: Some(true),
off_chain: Some(true),
storage: Some(Storage::Auto),
async_: None,
}),
)?;
println!("ID of logged message: {}", result.message_id.unwrap());
Ok(())
}
Accessibility
Private
Request
POST /messages/log
Parameters
- Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
message |
String|Object | The message to record. If an object is passed instead, it is expected that the message be passed in chunks. |
data |
String | (optional) The next message data chunk. The actual message's contents should be comprised of one or more data chunks. |
isFinal |
Boolean | (optional, default: true ) Indicates whether this is the final message data chunk. |
continuationToken |
String | (optional) Indicates that this is a continuation message data chunk. It should be filled with the value returned in the continuationToken field of the response to the request used to pass the previous message data chunk. |
options |
Object | (optional) |
encoding |
String | (optional, default: utf8 ) Value identifying the encoding of the message. Valid options: utf8 , base64 , hex . |
encrypt |
Boolean | (optional, default: true ) Indicates whether message should be encrypted before storing it. |
offChain |
Boolean | (optional, default: true ) Indicates whether message should be logged as a Catenis off-chain message. |
storage |
String | (optional, default: auto ) Value identifying where the message should be stored. Valid options: auto , embedded , external . The value embedded specifies that the message should be stored on the blockchain transaction itself; the value external specifies that the message should be stored in an external repository; and the value auto is used to specify that the message be embedded whenever possible otherwise it should be stored in the external storage. |
async |
Boolean | (optional, default: false ) Indicates whether processing — storage of message to the blockchain — should be done asynchronously. |
Sample response:
{
"status": "success",
"data": {
"messageId": "ouczbRbcgo3F8XoC6ejE"
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
continuationToken |
String | (only returned if passing message in chunks and last message data chunk was not final) Token to be used when sending the following message data chunk. |
messageId |
String | (only returned after message has been processed) ID of the logged message. |
provisionalMessageId |
String | (only returned if doing asynchronous processing after the whole message's contents are passed) ID of provisional message. |
Possible errors
Migrate Asset
Migrate an amount of a previously exported asset to/from the foreign blockchain token.
The migration can occur in two directions: outward or inward. When out-migrating, the specified amount is deducted from the asset and credited to the foreign token. Otherwise, when in-migrating, the specified amount is deducted from the foreign token and credited to the asset.
Sample request:
POST /api/0.13/assets/aH2AkrrL55GcThhPNa3J/migrate/ethereum HTTP/1.1
X-BCoT-Timestamp: 20210810T121125Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20210810/ctn1_request, Signature=e0493fed7f758c444bc29be683723165e255df40549ecc60d292d5745e1dcb68
Content-Type: application/json; charset=utf-8
Host: localhost:3000
Connection: close
User-Agent: Paw/3.2.3 (Macintosh; OS X/11.5.0) GCDHTTPRequest
Content-Length: 108
{"migration":{"direction":"outward","amount":50.5,"destAddress":"0xe247c9BfDb17e7D8Ae60a744843ffAd19C784943"}}
curl -X "POST" "http://localhost:3000/api/0.13/assets/aH2AkrrL55GcThhPNa3J/migrate/ethereum" \
-H 'X-BCoT-Timestamp: 20210809T203625Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20210809/ctn1_request, Signature=a94d8ed1df52dfd21959f3a04436bdc68f47ea41685cd7f20fbf126f6fec63df' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"migration": {
"amount": 50.5,
"direction": "outward",
"destAddress": "0xe247c9BfDb17e7D8Ae60a744843ffAd19C784943"
}
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aH2AkrrL55GcThhPNa3J';
var foreignBlockchain = 'ethereum';
ctnApiClient.migrateAsset(assetId, foreignBlockchain, {
direction: 'outward',
amount: 50.5,
destAddress: '0xe247c9BfDb17e7D8Ae60a744843ffAd19C784943'
}, function (error, data) {
if (error) {
// Process error
}
else {
// Process returned data
console.log('Pending asset migration:', data);
// Start polling for asset migration outcome
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aH2AkrrL55GcThhPNa3J';
var foreignBlockchain = 'ethereum';
ctnApiClient.migrateAsset(assetId, foreignBlockchain, {
direction: 'outward',
amount: 50.5,
destAddress: '0xe247c9BfDb17e7D8Ae60a744843ffAd19C784943'
}, function (error, data) {
if (error) {
// Process error
}
else {
// Process returned data
console.log('Pending asset migration:', data);
// Start polling for asset migration outcome
}
});
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$assetId = 'aH2AkrrL55GcThhPNa3J';
$foreignBlockchain = 'ethereum';
try {
$data = $ctnApiClient->migrateAsset($assetId, $foreignBlockchain, [
'direction' => 'outward',
'amount' => 50.5,
'destAddress' => '0xe247c9BfDb17e7D8Ae60a744843ffAd19C784943'
]);
// Process returned data
echo 'Pending asset migration: ' . print_r($data, true);
// Start polling for asset migration outcome
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let asset_id = "aH2AkrrL55GcThhPNa3J";
let result = ctn_client.migrate_asset(
asset_id,
ForeignBlockchain::Ethereum,
AssetMigration::Info(AssetMigrationInfo {
direction: AssetMigrationDirection::Outward,
amount: 50.5,
dest_address: Some(String::from("0xe247c9BfDb17e7D8Ae60a744843ffAd19C784943")),
}),
None,
)?;
println!("Pending asset migration: {:?}", result);
// Start polling for asset migration outcome
Ok(())
}
Accessibility
Private
Request
POST /assets/:assetId
/migrate/:foreignBlockchain
Parameters
URL parameters:
assetId
: The ID of the asset to migrate an amount of it.foreignBlockchain
: The key identifying the foreign blockchain. Valid options:ethereum
,binance
,polygon
.
Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
migration |
Object|String | Object describing a new asset migration, or the ID of the asset migration to be reprocessed. |
direction |
String | The direction of the migration. Valid options: outward , inward . |
amount |
Number | The amount of the asset to be migrated. |
destAddress |
String | (optional, only required for an out-migration) The address of the account on the foreign blockchain that should be credited with the specified amount of the foreign token. |
options |
Object | (optional) |
consumptionProfile |
String | (optional) Name of the foreign blockchain's native coin consumption profile to use. Valid options: fastest , fast , average , slow . |
estimateOnly |
Boolean | (optional, default: false ) When set, indicates that no asset migration should be executed but only the estimated price (in the foreign blockchain's native coin) to fulfill the operation should be returned. |
Sample response (regular migration):
{
"status": "success",
"data": {
"migrationId": "gq8x3efLpEXTkGQchHTb",
"catenisService": {
"status": "fulfilled",
"txid": "61fcb4feb64ecf3b39b4bb6d64eb9cc68a58ba1d892f981ef568d07b7aa11fdf"
},
"foreignTransaction": {
"txid": "0x212ab54f136a6fc1deae9ec217ef2d0417615178777131e8bb6958447fd20fe7",
"isPending": true
},
"status": "pending",
"date": "2021-08-03T18:51:26.631Z"
}
}
Sample response (estimate only):
{
"status": "success",
"data": {
"estimatedPrice": "0.001723913"
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
migrationId |
String | (not returned for estimate only) A unique ID used to identify this asset migration. |
catenisService |
Object | (not returned for estimate only) Information about the execution of the migrate asset Catenis service. |
status |
String | The current state of the service's execution. One of: awaiting , failure , or fulfilled . |
txid |
String | (only returned if the service is successfully fulfilled) The ID of the Catenis transaction issued to fulfill the service. |
error |
String | (only returned if the service's execution has failed) An error message describing what went wrong when executing the service. |
foreignTransaction |
Object | (not returned for estimate only) Information about the transaction issued on the foreign blockchain to mint/burn the amount of the foreign token. |
txid |
String | The ID (or hash) of the foreign blockchain transaction. |
isPending |
Boolean | Indicates whether the foreign blockchain transaction is yet to be executed. |
success |
Boolean | (only returned after the foreign blockchain transaction is executed) Indicates whether the foreign blockchain transaction has been successfully executed or not. |
error |
String | (only returned if the foreign blockchain transaction's execution has failed) An error message describing what went wrong when executing the transaction. |
status |
String | (not returned for estimate only) The current state of the asset migration. One of: pending , interrupted , success , or error . |
date |
String | (not returned for estimate only) ISO 8601 formatted date and time when the asset amount has been migrated. |
estimatedPrice |
String | (only returned for estimate only) A text value representing the price, in the foreign blockchain's native coin, required to execute the foreign blockchain transaction. |
Possible errors
Read Message
Retrieves the contents of a message that had been previously recorded on the blockchain.
Sample request:
GET /api/0.13/messages/oDWPuD5kjCsEiNEEWwrW?encoding=utf8 HTTP/1.1
X-BCoT-Timestamp: 20180215T112048Z
Authorization: CTN1-HMAC-SHA256 Credential=dmM2Dz32agLSGsSuoxsR/20180215/ctn1_request, Signature=10b1299fdf935544b44e3e1e8de7d3f3df03df9ddc35db0127d5ab0cafa36cbb
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/messages/oDWPuD5kjCsEiNEEWwrW?encoding=utf8" \
-H 'X-BCoT-Timestamp: 20180215T112120Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dmM2Dz32agLSGsSuoxsR/20180215/ctn1_request, Signature=84ddc0f0e3a3cadab6011b18962912bdf62bfcd2234e0984513a1856fd88c1c1'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var messageId = 'oDWPuD5kjCsEiNEEWwrW';
ctnApiClient.readMessage(messageId, 'utf8', function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Read message:', data.msgData.message);
if (data.msgInfo.action === 'send') {
console.log('Message sent from:', data.msgInfo.from);
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var messageId = 'oDWPuD5kjCsEiNEEWwrW';
ctnApiClient.readMessage(messageId, 'utf8', function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Read message:', data.message);
if (data.action === 'send') {
console.log('Message sent from:', data.from);
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$messageId = 'oDWPuD5kjCsEiNEEWwrW';
try {
$data = $ctnApiClient->readMessage($messageId, 'utf8');
// Process returned data
echo 'Read message: ' . $data->message . PHP_EOL;
if ($data->action === 'send') {
echo 'Message sent from: ' . print_r($data->from, true);
}
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let message_id = "oDWPuD5kjCsEiNEEWwrW";
let result = ctn_client.read_message(
message_id,
Some(ReadMessageOptions {
encoding: Some(Encoding::UTF8),
continuation_token: None,
data_chunk_size: None,
async_: None,
}),
)?;
println!("Read message: {}", result.msg_data.unwrap());
let msg_info = result.msg_info.unwrap();
if msg_info.action == RecordMessageAction::Send {
println!("Message sent from: {:?}", msg_info.from.unwrap());
}
Ok(())
}
Accessibility
Private
Request
GET /messages/:messageId
Parameters
URL parameters:
messageId
: The ID of the message to read.
Query string parameters:
encoding
: (optional, default:utf8
) The encoding to be used for the contents of the message. Valid values:utf8
,base64
,hex
.continuationToken
: (optional) Indicates that this is a continuation call and that the following message data chunk should be returned. It should be filled with the value returned in thecontinuationToken
field of the response to the request used to retrieve the previous message data chunk, or the request to the Retrieve Message Progress API method.dataChunkSize
: (optional) Size, in bytes, of the largest message data chunk that should be returned. This is effectively used to signal that the message should be read in chunks. It must be an integer value between 1,024 (1 KB) and 15,728,640 (15 MB).async
: (optional, default:false
) A boolean value indicating whether processing — retrieval of message from the blockchain — should be done asynchronously.
Sample response:
{
"status": "success",
"data": {
"msgInfo": {
"action": "send",
"from": {
"deviceId": "dv3htgvK7hjnKx3617Re",
"name": "Catenis device #1"
}
},
"msgData": "This is only a test"
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
msgInfo |
Object | (only returned along with the msgData field if not reading the message in chunks or for the first message data chunk returned) Info about the read message. |
action |
String | Action originally performed on the message. Possible values: log , send . The value log indicates that this is a logged message, and the value send indicates that this is a sent message. |
from |
Object | (only returned for sent messages) Identifies the virtual device that sent the message — the origin device. |
deviceId |
String | The device ID of the origin device. |
name |
String | (only returned if origin device has this data, and the virtual device issuing the request has the necessary permission right) The name of the origin device. |
prodUniqueId |
String | (only returned if origin device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the origin device. |
msgData |
String | (always returned except when cachedMessageId field is returned) The contents of the message formatted using the specified encoding. When reading the message in chunks, this corresponds to a message data chunk. In that case, additional calls to this API method might be necessary to read the whole message's contents. |
continuationToken |
String | (only returned along with the msgData field if the whole message's contents have not yet been returned) Token to be used when requesting the following message data chunk. |
cachedMessageId |
String | (only returned as a response to the initial call to this API method to read a given message asynchronously — async parameter set to true ) Cached message ID. |
Possible errors
Reissue Asset
Issues an additional amount of an existing asset.
Sample request:
POST /api/0.13/assets/aQjlzShmrnEZeeYBZihc/issue/ HTTP/1.1
X-BCoT-Timestamp: 20180417T004201Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=71d61d674882e0bcfadcda962cf3393b300af6f0cbbc5fb211f1f33d5bbd8b3a
Content-Type: application/json; charset=utf-8
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
Content-Length: 60
{"amount":450,"holdingDevice":{"id":"dv3htgvK7hjnKx3617Re"}}
curl -X "POST" "https://sandbox.catenis.io/api/0.13/assets/aQjlzShmrnEZeeYBZihc/issue/" \
-H 'X-BCoT-Timestamp: 20180417T004241Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=bfed2a3062c5ee48623ff863d5bc5bedee85189303617be7b01b080c8d9ca950' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"amount": 450,
"holdingDevice": {
"id": "dv3htgvK7hjnKx3617Re"
}
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aQjlzShmrnEZeeYBZihc';
var holdingDevice = {
id: 'dv3htgvK7hjnKx3617Re'
};
ctnApiClient.reissueAsset(assetId, 450.00, holdingDevice,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Total existent asset balance (after issuance):', data.totalExistentBalance);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aQjlzShmrnEZeeYBZihc';
var holdingDevice = {
id: 'dv3htgvK7hjnKx3617Re'
};
ctnApiClient.reissueAsset(assetId, 450.00, holdingDevice,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Total existent asset balance (after issuance):', data.totalExistentBalance);
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$assetId = 'aQjlzShmrnEZeeYBZihc';
$holdingDevice = [
'id' => 'dv3htgvK7hjnKx3617Re'
];
try {
$data = $ctnApiClient->reissueAsset($assetId, 450.00, $holdingDevice);
// Process returned data
echo 'Total existent asset balance (after issuance): ' . $data->totalExistentBalance . PHP_EOL;
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let asset_id = "aQjlzShmrnEZeeYBZihc";
let holding_device = DeviceId {
id: String::from("dv3htgvK7hjnKx3617Re"),
is_prod_unique_id: None,
};
let result = ctn_client.reissue_asset(
asset_id,
650.25,
Some(holding_device),
)?;
println!("Total existent asset balance (after issuance): {}", result.total_existent_balance);
Ok(())
}
Accessibility
Private
Request
POST /assets/:assetId
/issue
Parameters
URL parameters:
assetId
: The ID of the asset to issue more units of it.
Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
amount |
Number | The amount of asset to issue. |
holdingDevice |
Object | (optional) Virtual device for which the asset is issued and that shall hold the issued amount. |
id |
String | The ID of the holding device. Should be a device ID unless isProdUniqueId is set. |
isProdUniqueId |
Boolean | (optional, default: false ) Indicates whether the supplied ID is a product unique ID. |
Sample response:
{
"status": "success",
"data": {
"totalExistentBalance": 1650
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
totalExistentBalance |
Number | Total balance of the asset in existence after specified amount has been issued. |
Possible errors
Reissue Non-Fungible Asset
Issues more non-fungible tokens for a previously created non-fungible asset.
Sample request (initial call):
POST /api/0.13/assets/non-fungible/ahfTzqgWAXnMR6Z57mcp/issue HTTP/1.1
X-BCoT-Timestamp: 20220817T134801Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220817/ctn1_request, Signature=a9b862ea223e8f0bb67b1cf50bd36fb94ebeaef55a94ebc6ae31048cc668ac49
Content-Type: application/json; charset=utf-8
Host: localhost:3000
Connection: close
User-Agent: Paw/3.3.6 (Macintosh; OS X/12.5.0) GCDHTTPRequest
Content-Length: 481
{"encryptNFTContents":true,"nonFungibleTokens":[{"metadata":{"name":"NFA9 NFT 3","description":"Third token of Catenis non-fungible asset #9"},"contents":{"data":"This is the contents of token #3 of Catenis non-fungible asset #9 (part #1)","encoding":"utf8"}},{"metadata":{"name":"NFA9 NFT 4","description":"Forth token of Catenis non-fungible asset #9"},"contents":{"data":"This is the contents of token #4 of Catenis non-fungible asset #9.","encoding":"utf8"}}],"isFinal":false}
curl -X "POST" "http://localhost:3000/api/0.13/assets/non-fungible/ahfTzqgWAXnMR6Z57mcp/issue" \
-H 'X-BCoT-Timestamp: 20220817T134801Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220817/ctn1_request, Signature=a9b862ea223e8f0bb67b1cf50bd36fb94ebeaef55a94ebc6ae31048cc668ac49' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"encryptNFTContents": true,
"nonFungibleTokens": [
{
"metadata": {
"name": "NFA9 NFT 3",
"description": "Third token of Catenis non-fungible asset #9"
},
"contents": {
"data": "This is the contents of token #3 of Catenis non-fungible asset #9 (part #1)",
"encoding": "utf8"
}
},
{
"metadata": {
"name": "NFA9 NFT 4",
"description": "Forth token of Catenis non-fungible asset #9"
},
"contents": {
"data": "This is the contents of token #4 of Catenis non-fungible asset #9.",
"encoding": "utf8"
}
}
],
"isFinal": false
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'ahfTzqgWAXnMR6Z57mcp';
ctnApiClient.reissueNonFungibleAsset(assetId, {
encryptNFTContents: true
}, [{
metadata: {
name: 'NFA9 NFT 3',
description: 'Third token of Catenis non-fungible asset #9'
},
contents: {
data: 'This is the contents of token #3 of Catenis non-fungible asset #9 (part #1)',
encoding: 'utf8'
}
}, {
metadata: {
name: 'NFA9 NFT 4',
description: 'Forth token of Catenis non-fungible asset #9'
},
contents: {
data: 'This is the contents of token #4 of Catenis non-fungible asset #9.',
encoding: 'utf8'
}
}],
false,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Continuation token:', data.continuationToken);
}
});
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'ahfTzqgWAXnMR6Z57mcp';
ctnApiClient.reissueNonFungibleAsset(assetId, {
encryptNFTContents: true
}, [{
metadata: {
name: 'NFA9 NFT 3',
description: 'Third token of Catenis non-fungible asset #9'
},
contents: {
data: 'This is the contents of token #3 of Catenis non-fungible asset #9 (part #1)',
encoding: 'utf8'
}
}, {
metadata: {
name: 'NFA9 NFT 4',
description: 'Forth token of Catenis non-fungible asset #9'
},
contents: {
data: 'This is the contents of token #4 of Catenis non-fungible asset #9.',
encoding: 'utf8'
}
}],
false,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Continuation token:', data.continuationToken);
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$assetId = 'ahfTzqgWAXnMR6Z57mcp';
try {
$data = $ctnApiClient->reissueNonFungibleAsset($assetId, [
'encryptNFTContents' => true
], [
[
'metadata' => [
'name' => 'NFA9 NFT 3',
'description' => 'Third token of Catenis non-fungible asset #9'
],
'contents' => [
'data' => 'This is the contents of token #3 of Catenis non-fungible asset #9 (part #1)',
'encoding' => 'utf8'
]
],
[
'metadata' => [
'name' => 'NFA9 NFT 4',
'description' => 'Forth token of Catenis non-fungible asset #9'
],
'contents' => [
'data' => 'This is the contents of token #4 of Catenis non-fungible asset #9.',
'encoding' => 'utf8'
]
]
], false);
// Process returned data
echo 'Continuation token: ' . $data->continuationToken . PHP_EOL;
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let asset_id = "ahfTzqgWAXnMR6Z57mcp";
let result = ctn_client.reissue_non_fungible_asset(
asset_id,
NFAssetReissuanceInfoOrContToken::ReissuanceInfo(NonFungibleAssetReissuanceInfo {
encrypt_nft_contents: Some(true),
holding_devices: None,
async_: None,
}),
Some(vec![
Some(NewNonFungibleTokenInfo {
metadata: Some(NewNonFungibleTokenMetadata {
name: String::from("NFA9 NFT 3"),
description: Some(String::from("Third token of non-fungible asset #9")),
custom: None,
}),
contents: Some(NewNonFungibleTokenContents {
data: String::from("This is the contents of token #3 of Catenis non-fungible asset #9 (part #1)"),
encoding: Encoding::UTF8
}),
}),
Some(NewNonFungibleTokenInfo {
metadata: Some(NewNonFungibleTokenMetadata {
name: String::from("NFA9 NFT 4"),
description: Some(String::from("Forth token of non-fungible asset #9")),
custom: None,
}),
contents: Some(NewNonFungibleTokenContents {
data: String::from("This is the contents of token #4 of Catenis non-fungible asset #9."),
encoding: Encoding::UTF8
}),
}),
]),
Some(false)
)?;
println!("Continuation token: {}", result.continuation_token.unwrap());
Ok(())
}
Sample request (final continuation call):
POST /api/0.13/assets/non-fungible/ahfTzqgWAXnMR6Z57mcp/issue HTTP/1.1
X-BCoT-Timestamp: 20220817T135103Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220817/ctn1_request, Signature=8083c6b45899fc6d77aa36978ece9c6aea02862b0cc68a4d16355ba50e090f37
Content-Type: application/json; charset=utf-8
Host: localhost:3000
Connection: close
User-Agent: Paw/3.3.6 (Macintosh; OS X/12.5.0) GCDHTTPRequest
Content-Length: 204
{"continuationToken":"bNg8PeRoTvzbqYyLmCg6","nonFungibleTokens":[{"contents":{"data":"; last part of the contents of the third token of Catenis non-fungible asset #9.","encoding":"utf8"}}],"isFinal":true}
curl -X "POST" "http://localhost:3000/api/0.13/assets/non-fungible/ahfTzqgWAXnMR6Z57mcp/issue" \
-H 'X-BCoT-Timestamp: 20220817T135103Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220817/ctn1_request, Signature=8083c6b45899fc6d77aa36978ece9c6aea02862b0cc68a4d16355ba50e090f37' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"continuationToken": "bNg8PeRoTvzbqYyLmCg6",
"nonFungibleTokens": [
{
"contents": {
"data": "; last part of the contents of the third token of Catenis non-fungible asset #9.",
"encoding": "utf8"
}
}
],
"isFinal": true
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'ahfTzqgWAXnMR6Z57mcp';
var continuationToken = 'bNg8PeRoTvzbqYyLmCg6';
ctnApiClient.reissueNonFungibleAsset(assetId, continuationToken, [{
contents: {
data: '; last part of the contents of the third token of Catenis non-fungible asset #9.',
encoding: 'utf8'
}
}],
true,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('IDs of newly issued non-fungible tokens:', data.nfTokenIds);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'ahfTzqgWAXnMR6Z57mcp';
var continuationToken = 'bNg8PeRoTvzbqYyLmCg6';
ctnApiClient.reissueNonFungibleAsset(assetId, continuationToken, [{
contents: {
data: '; last part of the contents of the third token of Catenis non-fungible asset #9.',
encoding: 'utf8'
}
}],
true,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('IDs of newly issued non-fungible tokens:', data.nfTokenIds);
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$assetId = 'ahfTzqgWAXnMR6Z57mcp';
$continuationToken = 'bNg8PeRoTvzbqYyLmCg6';
try {
$data = $ctnApiClient->reissueNonFungibleAsset($assetId, $continuationToken, [
[
'contents' => [
'data' => '; last part of the contents of the third token of Catenis non-fungible asset #9.',
'encoding' => 'utf8'
]
]
], true);
// Process returned data
echo 'IDs of newly issued non-fungible tokens: ' . $data->nfTokenIds . PHP_EOL;
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let asset_id = "ahfTzqgWAXnMR6Z57mcp";
let continuation_token = "bNg8PeRoTvzbqYyLmCg6";
let result = ctn_client.reissue_non_fungible_asset(
asset_id,
NFAssetReissuanceInfoOrContToken::ContinuationToken(String::from(continuation_token)),
Some(vec![
Some(NewNonFungibleTokenInfo {
metadata: None,
contents: Some(NewNonFungibleTokenContents {
data: String::from("; last part of the contents of the third token of Catenis non-fungible asset #9."),
encoding: Encoding::UTF8
}),
}),
]),
Some(true)
)?;
println!("IDs of newly issued non-fungible tokens: {:?}", result.nf_token_ids.unwrap());
Ok(())
}
Accessibility
Private
Request
POST /assets/non-fungible/:assetId
/issue
Parameters
URL parameters:
assetId
: The ID of the non-fungible asset for which more non-fungible tokens should be issued.
Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
encryptNFTContents |
Boolean | (optional, default: true ; should be omitted in a continuation call) Indicates whether the contents of the non-fungible tokens being issued should be encrypted before being stored. |
holdingDevices |
Object|Array(Object) | (optional; should be omitted in a continuation call) A single virtual device or a list of virtual devices that will hold the issued non-fungible tokens. |
id |
String | The ID of the holding device. Should be a device ID unless isProdUniqueId is set. |
isProdUniqueId |
Boolean | (optional, default: false ) Indicates whether the supplied ID is a product unique ID. |
async |
Boolean | (optional, default: false ; should be omitted in a continuation call) Indicates whether processing should be done asynchronously. |
continuationToken |
String | (optional; should be included only in a continuation call) This signals a continuation call of the asset issuance. It should be filled with the continuation token returned by the previous call. |
nonFungibleTokens |
Array(Object) | (optional; may be omitted in the final continuation call) List with the properties of the non-fungible tokens to be issued. |
metadata |
Object | (optional; should be omitted in a continuation call) The properties of the non-fungible token to issue. |
name |
String | The name of the non-fungible token. |
description |
String | (optional) A description of the non-fungible token. |
custom |
Object | (optional) User defined, custom properties of the non-fungible token. |
sensitiveProps |
Object | (optional) User defined, sensitive properties of the non-fungible token. Sensitive properties are encrypted before being stored. |
<prop_name> |
* | A custom, sensitive property identified by prop_name . |
<prop_name> |
* | A custom property identified by prop_name . |
contents |
Object | (optional; may be omitted in the initial call) The contents of the non-fungible token to issue. |
data |
String | An additional chunk of data of the non-fungible token's contents. |
encoding |
String | (optional, default: base64 ) The encoding of the contents data chunk. Valid options: utf8 , base64 , hex . |
isFinal |
Boolean | (optional, default: true ) Indicates whether this is the final call of the asset issuance. There should be no more continuation calls after this is set. |
Sample response (non-final call):
{
"status": "success",
"data": {
"continuationToken": "bNg8PeRoTvzbqYyLmCg6"
}
}
Sample response (final call, no asynchronous processing):
{
"status": "success",
"data": {
"nfTokenIds": [
"tquy3RRz8vd5BFiZyw99",
"tNp8btQLcSyMmF5mzcS3"
]
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
continuationToken |
String | (only returned for a non-final call) The continuation token to be used in the next continuation call. |
assetIssuanceId |
String | (only returned for a final call when doing processing asynchronously) The asset issuance ID. Used for retrieving the progress of an asynchronous non-fungible asset issuance. |
nfTokenIds |
Array(String) | (only returned for a final call when not doing processing asynchronously) A list of the IDs of the issued non-fungible tokens. |
Possible errors
Retrieve Asset Info
Gets information about a given asset.
Sample request:
GET /api/0.13/assets/aQjlzShmrnEZeeYBZihc HTTP/1.1
X-BCoT-Timestamp: 20180417T143840Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=d73532614d4e46fb4e9be59255a660b540a122322aa7800fcb8a0ea4c3a0e40a
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/assets/aQjlzShmrnEZeeYBZihc" \
-H 'X-BCoT-Timestamp: 20180417T143900Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=b6501dab96c6838807817c63d9e75f5020806c5a4a0075558a7ff3477b468a1a'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aQjlzShmrnEZeeYBZihc';
ctnApiClient.retrieveAssetInfo(assetId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Asset info:', data);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aQjlzShmrnEZeeYBZihc';
ctnApiClient.retrieveAssetInfo(assetId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Asset info:', data);
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$assetId = 'aQjlzShmrnEZeeYBZihc';
try {
$data = $ctnApiClient->retrieveAssetInfo($assetId);
// Process returned data
echo 'Asset info:' . print_r($data, true);
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let asset_id = "aQjlzShmrnEZeeYBZihc";
let result = ctn_client.retrieve_asset_info(
asset_id,
)?;
println!("Asset info: {:?}", result);
Ok(())
}
Accessibility
Private
Request
GET /assets/:assetId
Parameters
- URL parameters:
assetId
: The ID of the asset to retrieve information.
Sample response:
{
"status": "success",
"data": {
"assetId": "aQjlzShmrnEZeeYBZihc",
"name": "XYZ001",
"description": "Testing asset #1",
"isNonFungible": false,
"canReissue": true,
"decimalPlaces": 2,
"issuer": {
"deviceId": "dnN3Ea43bhMTHtTvpytS",
"name": "deviceB",
"prodUniqueId": "XYZABC001"
},
"totalExistentBalance": 1650
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
assetId |
String | The ID of the asset. |
name |
String | The name of the asset. |
description |
String | The description of the asset. |
isNonFungible |
Boolean | Indicates whether this is a non-fungible asset. |
canReissue |
Boolean | Indicates whether more units of this asset can be issued. |
decimalPlaces |
Number | The maximum number of decimal places that can be used to specify a fractional amount of this asset. |
issuer |
Object | The virtual device that originally issued this asset — the issuing device. |
deviceId |
String | The device ID of the issuing device. |
name |
String | (only returned if issuing device has this data, and the virtual device issuing the request has the necessary permission right) The name of the issuing device. |
prodUniqueId |
String | (only returned if issuing device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the issuing device. |
totalExistentBalance |
Number | The current total balance of the asset in existence. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid asset ID Invalid parameters: <param_list> |
403 | No permission to retrieve asset info |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
Retrieve Asset Issuance History
Gets a list of asset issuance events for a given asset that took place within a specified time frame.
Sample request:
GET /api/0.13/assets/aQjlzShmrnEZeeYBZihc/issuance?startDate=20170101T000000Z&limit=200&skip=0 HTTP/1.1
X-BCoT-Timestamp: 20180417T182853Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=57d779fbb24593ba4eff574e0c87961a3c39561cb90d99546d5041cdd7e964a9
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/assets/aQjlzShmrnEZeeYBZihc/issuance?startDate=20170101T000000Z&limit=200&skip=0" \
-H 'X-BCoT-Timestamp: 20180417T182836Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=4990e4df2d0d73d01cd251dab65b6f4d2f702b43eb517d88c5ff3038d0bbd1f6'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aQjlzShmrnEZeeYBZihc';
ctnApiClient.retrieveAssetIssuanceHistory(assetId, '20170101T000000Z', null, 200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
data.issuanceEvents.forEach(function (issuanceEvent, idx) {
console.log('Issuance event #', idx + 1, ':');
console.log(' - issued amount:', issuanceEvent.amount);
console.log(' - device to which issued amount had been assigned:', issuanceEvent.holdingDevice);
console.log(' - date of issuance:', issuanceEvent.date);
});
if (data.hasMore) {
console.log('Not all asset issuance events have been returned');
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aQjlzShmrnEZeeYBZihc';
ctnApiClient.retrieveAssetIssuanceHistory(assetId, '20170101T000000Z', null, 200, 0,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
data.issuanceEvents.forEach(function (issuanceEvent, idx) {
console.log('Issuance event #', idx + 1, ':');
console.log(' - issued amount:', issuanceEvent.amount);
console.log(' - device to which issued amount had been assigned:', issuanceEvent.holdingDevice);
console.log(' - date of issuance:', issuanceEvent.date);
});
if (data.hasMore) {
console.log('Not all asset issuance events have been returned');
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$assetId = 'aQjlzShmrnEZeeYBZihc';
try {
$data = $ctnApiClient->retrieveAssetIssuanceHistory($assetId, '20170101T000000Z', null, 200, 0);
// Process returned data
forEach($data->issuanceEvents as $idx => $issuanceEvent) {
echo 'Issuance event #', ($idx + 1) . ':' . PHP_EOL;
echo ' - issued amount: ' . $issuanceEvent->amount . PHP_EOL;
echo ' - device to which issued amount had been assigned: ' . print_r($issuanceEvent->holdingDevice, true);
echo ' - date of issuance: ' . $issuanceEvent->date . PHP_EOL;
}
if ($data->hasMore) {
echo 'Not all asset issuance events have been returned' . PHP_EOL;
}
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let asset_id = "aQjlzShmrnEZeeYBZihc";
let result = ctn_client.retrieve_asset_issuance_history(
asset_id,
Some("2017-01-01T00:00:00Z".into()),
None,
Some(200),
Some(0),
)?;
for idx in 0..result.issuance_events.len() {
let issuance_event = &result.issuance_events[idx];
println!("Issuance event #{}:", idx + 1);
println!(" - asset amount: {}", issuance_event.amount);
println!(" - device to which issued amount had been assigned: {:?}", issuance_event.holding_device);
println!(" - date of issuance: {}", issuance_event.date);
}
if result.has_more {
println!("Not all asset issuance events have been returned");
}
Ok(())
}
Accessibility
Private
Request
GET /assets/:assetId
/issuance
Parameters
- URL parameters:
assetId
: The ID of the asset to retrieve the issuance history.
- Query string parameters:
startDate
: (optional) ISO 8601 formatted date and time specifying the inclusive lower bound of the time frame within which amounts of the asset have been issued.endDate
: (optional) ISO 8601 formatted date and time specifying the inclusive upper bound of the time frame within which amounts of the asset have been issued.limit
: (optional, default:500
) Maximum number of asset issuance events that should be returned. Must be a positive integer value not greater than 500.skip
: (optional, default:0
) Number of asset issuance events that should be skipped (from beginning of list of matching events) and not returned. Must be a non-negative (includes zero) integer value.
Sample response (regular asset):
{
"status": "success",
"data": {
"issuanceEvents": [
{
"amount": 1200,
"holdingDevice": {
"deviceId": "dnN3Ea43bhMTHtTvpytS",
"name": "deviceB",
"prodUniqueId": "XYZABC001"
},
"date": "2018-03-27T21:43:15.050Z"
},
{
"amount": 450,
"holdingDevice": {
"deviceId": "dv3htgvK7hjnKx3617Re",
"name": "Catenis device #1"
},
"date": "2018-03-28T12:20:31.738Z"
}
],
"hasMore": false
}
}
Sample response (non-fungible asset):
{
"status": "success",
"data": {
"issuanceEvents": [
{
"nfTokenIds": [
"tTwEvLSN9SnSr95FdYPq",
"tmNvCvqLssu64tzZDqZa"
],
"holdingDevices": [
{
"deviceId": "dnN3Ea43bhMTHtTvpytS",
"name": "deviceB",
"prodUniqueId": "XYZABC001"
},
{
"deviceId": "dv3htgvK7hjnKx3617Re",
"name": "Catenis device #1"
}
],
"date": "2022-06-14T15:28:51.629Z"
},
{
"nfTokenIds": [
"tQyJrga3ke65RR23iyr2",
"tf2rbknDoo9wPsKBkskj",
"t9yNnxYD6jNk4pogi4fe"
],
"holdingDevices": [
{
"deviceId": "dnN3Ea43bhMTHtTvpytS",
"name": "deviceB",
"prodUniqueId": "XYZABC001"
}
],
"date": "2022-08-02T12:26:53.758Z"
}
],
"hasMore": false
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
issuanceEvents |
Array(Object) | The list of asset issuance events returned. The events are sorted in ascending order in regard to the returned date field. |
amount |
Number | (only returned for regular (fungible) assets) The amount of the asset issued. |
nfTokenIds |
Array(String) | (only returned for non-fungible assets) List of the IDs of the non-fungible tokens of the asset that have been issued. |
holdingDevice |
Object | (only returned for regular (fungible) assets) The virtual device to which the issued amount was assigned. |
deviceId |
String | The device ID of the holding device. |
name |
String | (only returned if holding device has this data, and the virtual device issuing the request has the necessary permission right) The name of the holding device. |
prodUniqueId |
String | (only returned if holding device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the holding device. |
holdingDevices |
Array(Object) | (only returned for non-fungible assets) List of the virtual devices to which the issued non-fungible tokens were assigned. |
deviceId |
String | The device ID of the holding device. |
name |
String | (only returned if holding device has this data, and the virtual device issuing the request has the necessary permission right) The name of the holding device. |
prodUniqueId |
String | (only returned if holding device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the holding device. |
date |
String | ISO 8601 formatted date and time when the asset has been issued. |
hasMore |
Boolean | Indicates whether there are more asset issuance events that satisfy the search criteria yet to be returned. |
Possible errors
Retrieve Device Identification Info
Gets the identification information of a given virtual device.
Sample request:
GET /api/0.13/devices/dv3htgvK7hjnKx3617Re HTTP/1.1
X-BCoT-Timestamp: 20180219T133757Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=ff2a8f3d8dc232d60208dc28f668351234ed25ead274e820ac081a480a275012
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/devices/dv3htgvK7hjnKx3617Re" \
-H 'X-BCoT-Timestamp: 20180219T133846Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180219/ctn1_request, Signature=74b0618fe8fe40278b3325cccdac350bed538a5faac86689c3d07e3f1df085f0'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var checkDeviceId = 'dv3htgvK7hjnKx3617Re';
ctnApiClient.retrieveDeviceIdentificationInfo(checkDeviceId, false, function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Device\'s Catenis node ID info:', data.catenisNode);
console.log('Device\'s client ID info:', data.client);
console.log('Device\'s own ID info:', data.device);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var checkDeviceId = 'dv3htgvK7hjnKx3617Re';
ctnApiClient.retrieveDeviceIdentificationInfo(checkDeviceId, false, function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Device\'s Catenis node ID info:', data.catenisNode);
console.log('Device\'s client ID info:', data.client);
console.log('Device\'s own ID info:', data.device);
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$checkDeviceId = 'dv3htgvK7hjnKx3617Re';
try {
$data = $ctnApiClient->retrieveDeviceIdentificationInfo($checkDeviceId);
// Process returned data
echo 'Device\'s Catenis node ID info:' . print_r($data->catenisNode, true);
echo 'Device\'s client ID info:' . print_r($data->client, true);
echo 'Device\'s own ID info:' . print_r($data->device, true);
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let check_device = DeviceId {
id: String::from("dv3htgvK7hjnKx3617Re"),
is_prod_unique_id: None,
};
let result = ctn_client.retrieve_device_identification_info(
check_device,
)?;
println!("Device's Catenis node ID info: {:?}", result.catenis_node);
println!("Device's client ID info: {:?}", result.client);
println!("Device's own ID info: {:?}", result.device);
Ok(())
}
Accessibility
Private
Request
GET /devices/:deviceId
Parameters
URL parameters:
deviceId
: The ID of the virtual device the identification info of which should be retrieved. Should be a device ID unlessisProdUniqueId
is set. The special valueself
can be used in place of the device ID of the virtual device issuing the request.
Query string parameters:
isProdUniqueId
: (optional, default:false
) Indicates whether the supplied ID is a product unique ID.
Sample response:
{
"status": "success",
"data": {
"catenisNode": {
"ctnNodeIndex": 0,
"name": "Catenis Hub",
"description": "Central Catenis node used to house clients that access the system through the Internet"
},
"client": {
"clientId": "cjNhuvGMUYoepFcRZadP",
"name": "My test client"
},
"device": {
"deviceId": "dv3htgvK7hjnKx3617Re",
"name": "Catenis device #1"
}
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
catenisNode |
Object | Information about the Catenis node where the client to which the specified virtual device belongs is defined. |
ctnNodeIndex |
Number | The index of the Catenis node. |
name |
String | (only returned if Catenis node has this data) The name of the Catenis node. |
description |
String | (only returned if Catenis node has this data) A short description about the Catenis node. |
client |
Object | Information about the client to which the specified virtual device belongs. |
clientId |
String | The client ID of the client. |
name |
String | (only returned if client has this data) The name of the client. |
device |
Object | Information about the specified virtual device itself. |
deviceId |
String | The device ID of the virtual device. |
name |
String | (only returned if virtual device has this data) The name of the virtual device. |
prodUniqueId |
String | (only returned if virtual device has this data) The product unique ID of the virtual device. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid device Invalid parameters: <param_list> |
403 | No permission to retrieve info |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
Retrieve Message Container
Gets information about the place where a previously recorded — either logged or sent — message is actually stored.
Sample request:
GET /api/0.13/messages/oDWPuD5kjCsEiNEEWwrW/container HTTP/1.1
X-BCoT-Timestamp: 20180215T200325Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180215/ctn1_request, Signature=f06dc359270c2a3a91326ef2e7fd5506fd75dc9740b2609ed796ce01b3f92afb
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/messages/oDWPuD5kjCsEiNEEWwrW/container" \
-H 'X-BCoT-Timestamp: 20180215T200350Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180215/ctn1_request, Signature=7e50993e18975294f7f22aae7ee7ef4e4d68425502e38961c40743b1f72194eb'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var messageId = 'oDWPuD5kjCsEiNEEWwrW';
ctnApiClient.retrieveMessageContainer(messageId, function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
if (data.offChain) {
console.log('IPFS CID of Catenis off-chain message envelope:', data.offChain.cid);
}
if (data.blockchain) {
console.log('ID of blockchain transaction containing the message:', data.blockchain.txid);
}
if (data.externalStorage) {
console.log('IPFS reference to message:', data.externalStorage.ipfs);
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var messageId = 'oDWPuD5kjCsEiNEEWwrW';
ctnApiClient.retrieveMessageContainer(messageId, function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
if (data.offChain) {
console.log('IPFS CID of Catenis off-chain message envelope:', data.offChain.cid);
}
if (data.blockchain) {
console.log('ID of blockchain transaction containing the message:', data.blockchain.txid);
}
if (data.externalStorage) {
console.log('IPFS reference to message:', data.externalStorage.ipfs);
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$messageId = 'oDWPuD5kjCsEiNEEWwrW';
try {
$data = $ctnApiClient->retrieveMessageContainer($messageId);
// Process returned data
if (isset($data->offChain)) {
echo 'IPFS CID of Catenis off-chain message envelope: ' . $data->offChain->cid . PHP_EOL;
}
if (isset($data->blockchain)) {
echo 'ID of blockchain transaction containing the message: ' . $data->blockchain->txid . PHP_EOL;
}
if (isset($data->externalStorage)) {
echo 'IPFS reference to message: ' . $data->externalStorage->ipfs . PHP_EOL;
}
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let message_id = "oDWPuD5kjCsEiNEEWwrW";
let result = ctn_client.retrieve_message_container(
message_id,
)?;
if let Some(off_chain) = result.off_chain {
println!("IPFS CID of Catenis off-chain message envelope: {}", off_chain.cid);
}
if let Some(blockchain) = result.blockchain {
println!("ID of blockchain transaction containing the message: {}", blockchain.txid);
}
if let Some(external_storage) = result.external_storage {
println!("IPFS reference to message: {}", external_storage.ipfs);
}
Ok(())
}
Accessibility
Private
Request
GET /messages/:messageId
/container
Parameters
- URL parameters:
messageId
: The ID of the message the container of which is to be retrieved.
Sample response:
{
"status": "success",
"data": {
"offChain": {
"cid": "QmUPNgbkB2esFHLZdS5rhD8wxFaCBU8JeBrBePWqMfSWub"
},
"blockchain": {
"txid": "e4080d2badac0b4d4524aa20cd3abfa2f1bdd05a15c85b9d156374c7c6bbfc82",
"isConfirmed": true
},
"externalStorage": {
"ipfs": "QmQ2UaYLHwSjU4VvHyD4SfCUyo7AvrufdNrX1kmsbtbn3w"
}
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
offChain |
Object | (only returned for Catenis off-chain messages) |
cid |
String | IPFS CID of Catenis off-chain message envelope data structure that holds the off-chain message's contents. |
blockchain |
Object | (for Catenis off-chain messages, this property refers to the transaction used to settle the message to the blockchain, and it is only returned at a later time after the settlement takes place) |
txid |
String | The ID of the blockchain transaction where the message was recorded. |
isConfirmed |
Boolean | Indicates whether the blockchain transaction has already been confirmed. |
externalStorage |
Object | (only returned if message is stored on an external storage rather than on the blockchain transaction itself) |
ipfs |
String | The hash used to reference the message on IPFS. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid message ID Invalid parameters: <param_list> |
403 | No permission to retrieve message container |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
Retrieve Message Origin *
Gets information about the origin of a previously recorded — either logged or sent — message.
Sample request:
GET /api/0.13/messages/oDWPuD5kjCsEiNEEWwrW/origin?msgToSign=This%20is%20only%20a%20test HTTP/1.1
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/messages/oDWPuD5kjCsEiNEEWwrW/origin?msgToSign=This%20is%20only%20a%20test"
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var ctnApiClient = new CtnApiClient({
environment: 'sandbox'
});
var messageId = 'oDWPuD5kjCsEiNEEWwrW';
ctnApiClient.retrieveMessageOrigin(messageId, 'Any text to be signed',
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
if (data.tx) {
console.log('Catenis message transaction info:', data.tx);
}
if (data.offChainMsgEnvelope) {
console.log('Off-chain message envelope info:', data.offChainMsgEnvelope);
}
if (data.proof) {
console.log('Origin proof info:', data.proof);
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var ctnApiClient = new CtnApiClient({
environment: 'sandbox'
});
var messageId = 'oDWPuD5kjCsEiNEEWwrW';
ctnApiClient.retrieveMessageOrigin(messageId, 'Any text to be signed',
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
if (data.tx) {
console.log('Catenis message transaction info:', data.tx);
}
if (data.offChainMsgEnvelope) {
console.log('Off-chain message envelope info:', data.offChainMsgEnvelope);
}
if (data.proof) {
console.log('Origin proof info:', data.proof);
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$ctnApiClient = new ApiClient(null, null, [
'environment' => 'sandbox'
]);
$messageId = 'oDWPuD5kjCsEiNEEWwrW';
try {
$data = $ctnApiClient->retrieveMessageOrigin($messageId, 'Any text to be signed');
// Process returned data
if (isset($data->tx)) {
echo 'Catenis message transaction info: ' . print_r($data->tx, true);
}
if (isset($data->offChainMsgEnvelope)) {
echo 'Off-chain message envelope info: ' . print_r($data->offChainMsgEnvelope, true);
}
if (isset($data->proof)) {
echo 'Origin proof info: ' . print_r($data->proof, true);
}
}
catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
};
fn main() -> Result<()> {
let ctn_client = CatenisClient::new_with_options(
None,
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let message_id = "oDWPuD5kjCsEiNEEWwrW";
let result = ctn_client.retrieve_message_origin(
message_id,
Some("Any text to be signed"),
)?;
if let Some(tx) = result.tx {
println!("Catenis message transaction info: {:?}", tx);
}
if let Some(off_chain_msg_env) = result.off_chain_msg_envelope {
println!("Off-chain message envelope info: {:?}", off_chain_msg_env);
}
if let Some(proof) = result.proof {
println!("Origin proof info: {:?}", proof);
}
Ok(())
}
Accessibility
Public
Request
GET /messages/:messageId
/origin
Parameters
URL parameters:
messageId
: The ID of the message the origin info of which is to be retrieved.
Query string parameters:
msgToSign
: (optional) A message (any text) to be signed using the Catenis message's origin device's private key. The resulting signature can then later be independently verified to prove the Catenis message's origin.
Sample response:
{
"status": "success",
"data": {
"tx": {
"txid": "e80b97c1ee45da349f774e4e509c0ddce56003fa737ef37ab22e1b676fe4a9c8",
"type": "Settle Off-Chain Messages",
"batchDoc": {
"cid": "QmT2kJRaShQbMEzjDVmqMtsjccqvUaemNNrXzkv6oVgi6d"
}
},
"offChainMsgEnvelope": {
"cid": "Qmd7xeEwwmWrJpovmTYhCTRjpfRPr9mtDxj7VRscrcqsgP",
"type": "Log Message",
"originDevice": {
"pubKeyHash": "25f154093fe70c4a45518f858a1edececf208ee6",
"deviceId": "drc3XdxNtzoucpw9xiRp",
"name": "TstDev1",
"prodUniqueId": "ABC123",
"ownedBy": {
"company": "Blockchain of Things",
"contact": "Cláudio de Castro",
"domains": [
"blockchainofthings.com",
"catenis.io"
]
}
}
},
"proof": {
"message": "This is only a test",
"signature": "H6bt6sl7T6VpOUQ1of0rjYEmT3u14h8gP7kmoWG4aEblNNc9Zx00tRaxcxPZgSxkmWH2427FBOFE5W/t9fgW4eU="
}
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
tx |
Object | (not returned for off-chain messages not yet settled to the blockchain) Information about the blockchain transaction used to record the Catenis message to the blockchain — the Catenis message transaction. |
txid |
String | ID of Catenis message transaction. |
type |
String | Type of Catenis message transaction. One of: Send Message , Log Message , or Settle Off-Chain Messages . |
batchDoc |
Object | (only returned for off-chain messages) Information about the batch document used to settle off-chain messages on the blockchain. |
cid |
String | Content ID (CID) of batch document on IPFS. |
originDevice |
Object | (not returned for off-chain messages) Information about the virtual device that recorded the message — the origin device. |
address |
String | Origin device's blockchain address used to generate the Catenis message transaction. |
deviceId |
String | Device ID of origin device. |
name |
String | (only returned if defined) Origin device's name. |
prodUniqueId |
String | (only returned if defined) Origin device's product unique ID. |
ownedBy |
Object | |
company |
String | (only returned if defined) Name of company that owns the origin device. |
contact |
String | (only returned if defined and company is returned) Name of company's contact. |
name |
String | (only returned if company is not returned) Name of the person who owns the origin device. |
domains |
Array(String) | (only returned if defined) List of internet domains owned by this company or person. |
offChainMsgEnvelope |
Object | (only returned for off-chain messages) Information about the off-chain message envelope data structure used to record the Catenis message on IPFS. |
cid |
String | Content ID (CID) of off-chain message envelope on IPFS. |
type |
String | Type of Catenis off-chain message. One of: Send Message , or Log Message . |
originDevice |
Object | (not returned for off-chain messages) Information about the virtual device that recorded the message — the origin device. |
pubKeyHash |
String | Hex-encoded hash of origin device's public key used to generate the off-chain message envelope. |
deviceId |
String | Device ID of origin device. |
name |
String | (only returned if defined) Origin device's name. |
prodUniqueId |
String | (only returned if defined) Origin device's product unique ID. |
ownedBy |
Object | |
company |
String | (only returned if defined) Name of company that owns the origin device. |
contact |
String | (only returned if defined and company is returned) Name of company's contact. |
name |
String | (only returned if company is not returned) Name of the person who owns the origin device. |
domains |
Array(String) | (only returned if defined) List of internet domains owned by this company or person. |
proof |
Object | (only returned if msgToSign parameter is supplied) |
message |
String | Message for which the signature was generated. |
signature |
String | Base64-encoded message's signature generated using origin device's private key. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid message ID |
403 | Message origin cannot be disclosed |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
Retrieve Message Progress
Retrieves the current status of the asynchronous processing of a message.
Sample request:
GET /api/0.13/messages/hfHtyPCS68toB9FjA8rM/progress HTTP/1.1
X-BCoT-Timestamp: 20190318T212628Z
Authorization: CTN1-HMAC-SHA256 Credential=dL8zaQDcyNvxRW3FqsJd/20190318/ctn1_request, Signature=d98b79672098eeea5f261e102d213168f757c3234a3ee28a2192b5acd739e664
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.8 (Macintosh; OS X/10.14.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/messages/hfHtyPCS68toB9FjA8rM/progress" \
-H 'X-BCoT-Timestamp: 20190318T212739Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dL8zaQDcyNvxRW3FqsJd/20190318/ctn1_request, Signature=3ee6e3c7fe58319e4b53a7342a38af2a923908bbe1da5864f5f800d7330abdc1'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var cachedMessageId = 'hfHtyPCS68toB9FjA8rM';
ctnApiClient.retrieveMessageProgress(cachedMessageId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Number of bytes processed so far:', data.progress.bytesProcessed);
if (data.progress.done) {
if (data.progress.success) {
// Get result
console.log('Asynchronous processing result:', data.result);
}
else {
// Process error
console.error('Asynchronous processing error: [', data.progress.error.code, ' ] -', data.progress.error.message);
}
}
else {
// Asynchronous processing not done yet. Continue pooling
}
}
});</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var cachedMessageId = 'hfHtyPCS68toB9FjA8rM';
ctnApiClient.retrieveMessageProgress(cachedMessageId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Number of bytes processed so far:', data.progress.bytesProcessed);
if (data.progress.done) {
if (data.progress.success) {
// Get result
console.log('Asynchronous processing result:', data.result);
}
else {
// Process error
console.error('Asynchronous processing error: [', data.progress.error.code, ' ] -', data.progress.error.message);
}
}
else {
// Asynchronous processing not done yet. Continue pooling
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$cachedMessageId = 'hfHtyPCS68toB9FjA8rM';
try {
$data = $ctnApiClient->retrieveMessageProgress($cachedMessageId);
// Process returned data
echo 'Number of bytes processed so far: ' . $data->progress->bytesProcessed . PHP_EOL;
if ($data->progress->done) {
if ($data->progress->success) {
// Get result
echo 'Asynchronous processing result: ' . $data->result . PHP_EOL;
}
else {
// Process error
echo 'Asynchronous processing error: [' . $data->progress->error->code . '] - '
. $data->progress->error->message . PHP_EOL;
}
} else {
// Asynchronous processing not done yet. Continue pooling
}
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let cached_message_id = "hfHtyPCS68toB9FjA8rM";
let result = ctn_client.retrieve_message_progress(
cached_message_id,
)?;
println!("Number of bytes processed so far: {}", result.progress.bytes_processed);
if result.progress.done {
if let Some(true) = result.progress.success {
// Get result
println!("Asynchronous processing result: {:?}", result.result.unwrap());
} else {
// Process error
let error = result.progress.error.unwrap();
println!("Asynchronous processing error: [{}] - {}", error.code, error.message);
}
} else {
// Asynchronous processing not done yet. Continue pooling
}
Ok(())
}
Accessibility
Private
Request
GET /messages/:messageId
/progress
Parameters
- URL parameters:
ephemeralMessageId
: ID of ephemeral message — either a provisional or a cached message — for which to return processing progress.
Sample response:
{
"status": "success",
"data": {
"action": "read",
"progress": {
"bytesProcessed": 28,
"done": true,
"success": true,
"finishDate": "2019-03-13T14:09:10.121Z"
},
"result": {
"messageId": "mt7ZYbBYpM3zcgAf3H8X",
"continuationToken": "kjXP2CZaSdkTKCi2jDi2"
}
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
action |
String | The action that was to be performed on the message. One of: log , send , or read . |
progress |
Object | Current processing status. |
bytesProcessed |
Number | Total number of bytes of message that had already been processed. |
done |
Boolean | Indicates whether processing has been finished. |
success |
Boolean | (only returned if processing has already been finished) Indicates whether message has been successfully processed. |
error |
Object | (only returned if processing finished with error) Error information. |
code |
Number | Numeric code — equivalent to an HTML status code — of the error that took place while processing the message. |
message |
String | Text describing the error that took place while processing the message. |
finishDate |
String | (only returned if processing has already been finished) ISO 8601 formatted date and time when processing was finalized. |
result |
Object | (only returned if processing finished successfully) Result of processing. |
messageId |
String | ID of the Catenis message. When logging or sending — action equals to log or send —, it is the ID of the resulting message. When reading — action equals to read —, it references the message being read. |
continuationToken |
String | (only returned if reading message — action equals to read ) The token that should be used to complete the read of the message. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid or expired ephemeral message Progress not available |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
Retrieve Non-Fungible Asset Issuance Progress
Retrieves the current progress of an asynchronous non-fungible asset issuance.
Sample request:
GET /api/0.13/assets/non-fungible/issuance/iwoTJPbnogCktrYpzwQn HTTP/1.1
X-BCoT-Timestamp: 20220817T143811Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220817/ctn1_request, Signature=de6a572fa907c591a581c30049c30ec24508a07f17510695b014f060d1adc60c
Host: localhost:3000
Connection: close
User-Agent: Paw/3.3.6 (Macintosh; OS X/12.5.0) GCDHTTPRequest
curl "http://localhost:3000/api/0.13/assets/non-fungible/issuance/iwoTJPbnogCktrYpzwQn" \
-H 'X-BCoT-Timestamp: 20220817T143811Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220817/ctn1_request, Signature=de6a572fa907c591a581c30049c30ec24508a07f17510695b014f060d1adc60c'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetIssuanceId = 'iwoTJPbnogCktrYpzwQn';
ctnApiClient.retrieveNonFungibleAssetIssuanceProgress(assetIssuanceId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
if (data.assetId) {
console.log('Reissuance for non-fungible asset:', data.assetId);
}
console.log('Percent processed:', data.progress.percentProcessed);
if (data.progress.done) {
if (data.progress.success) {
// Display result
if (data.result.assetId) {
console.log('ID of newly created non-fungible asset:', data.result.assetId);
}
console.log('IDs of newly issued non-fungible tokens:', data.result.nfTokenIds);
}
else {
// Process error
console.error('Asynchronous processing error: [', data.progress.error.code, ' ] -', data.progress.error.message);
}
}
else {
// Asynchronous processing not done yet. Continue pooling
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetIssuanceId = 'iwoTJPbnogCktrYpzwQn';
ctnApiClient.retrieveNonFungibleAssetIssuanceProgress(assetIssuanceId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
if (data.assetId) {
console.log('Reissuance for non-fungible asset:', data.assetId);
}
console.log('Percent processed:', data.progress.percentProcessed);
if (data.progress.done) {
if (data.progress.success) {
// Display result
if (data.result.assetId) {
console.log('ID of newly created non-fungible asset:', data.result.assetId);
}
console.log('IDs of newly issued non-fungible tokens:', data.result.nfTokenIds);
}
else {
// Process error
console.error('Asynchronous processing error: [', data.progress.error.code, ' ] -', data.progress.error.message);
}
}
else {
// Asynchronous processing not done yet. Continue pooling
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$assetIssuanceId = 'iwoTJPbnogCktrYpzwQn';
try {
$data = $ctnApiClient->retrieveNonFungibleAssetIssuanceProgress($assetIssuanceId);
// Process returned data
if (isset($data->assetId)) {
echo 'Reissuance for non-fungible asset:: ', $data->assetId . PHP_EOL;
}
echo 'Percent processed: ', $data->progress->percentProcessed . PHP_EOL;
if ($data->progress->done) {
if ($data->progress->success) {
// Display result
if (isset($data->result->assetId)) {
echo 'ID of newly created non-fungible asset: ' . $data->result->assetId . PHP_EOL;
}
echo 'IDs of newly issued non-fungible tokens: ' . implode(', ', $data->result->nfTokenIds) . PHP_EOL;
} else {
// Process error
echo 'Asynchronous processing error: [' . $data->progress->error->code . '] - '
. $data->progress->error->message . PHP_EOL;
}
} else {
// Asynchronous processing not done yet. Continue pooling
}
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let issuance_id = "iwoTJPbnogCktrYpzwQn";
let result = ctn_client.retrieve_non_fungible_asset_issuance_progress(
issuance_id,
)?;
if let Some(asset_id) = result.asset_id {
println!("Reissuance for non-fungible asset: {}", asset_id);
}
println!("Percent processed: {}", result.progress.percent_processed.to_string());
if result.progress.done {
if let Some(true) = result.progress.success {
// Get result
let issuance_result = result.result.unwrap();
if let Some(asset_id) = issuance_result.asset_id {
println!("ID of newly created non-fungible asset: {}", asset_id);
}
println!("IDs of newly issued non-fungible tokens:: {:?}", issuance_result.nf_token_ids);
} else {
// Process error
let error = result.progress.error.unwrap();
println!("Asynchronous processing error: [{}] - {}", error.code, error.message);
}
} else {
// Asynchronous processing not done yet. Continue pooling
}
Ok(())
}
Accessibility
Private
Request
GET /assets/non-fungible/issuance/:issuanceId
Parameters
- URL parameters:
issuanceId
: The ID of the non-fungible asset issuance the processing progress of which should be retrieved.
Sample response:
{
"status": "success",
"data": {
"assetId": "ahfTzqgWAXnMR6Z57mcp",
"progress": {
"percentProcessed": 100,
"done": true,
"success": true,
"finishDate": "2022-08-17T14:37:59.899Z"
},
"result": {
"nfTokenIds": [
"ttbG9ia4AjdP5Pm7WaLG"
]
}
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
assetId |
String | (only returned in case of re-issuance) The ID of the non-fungible asset for which more non-fungible tokens are being issued. |
progress |
Object | Current processing status. |
percentProcessed |
Number | The percentage of the total processing that has been already completed. |
done |
Boolean | Indicates whether the processing has been finished. |
success |
Boolean | (only returned if the processing has already been finished) Indicates whether the asset issuance has been successfully completed. |
error |
Object | (only returned if the processing finished with error) Information about the error that took place while processing the asset issuance. |
code |
Number | Numeric code — equivalent to an HTML status code — of the error. |
message |
String | Text describing the error. |
finishDate |
String | (only returned if the processing has already been finished) ISO 8601 formatted date and time when processing has been finalized. |
result |
Object | (only returned if the processing finished successfully) The result of the asset issuance. |
assetId |
String | (not returned in case of re-issuance) The ID of the newly created Catenis non-fungible asset. |
nfTokenIds |
Array(String) | List of the IDs of the newly issued non-fungible tokens. |
Possible errors
Retrieve Non-Fungible Token
Retrieves the data associated with a non-fungible token.
Sample request:
GET /api/0.13/assets/non-fungible/tokens/t76Yzrbqcjbtehk6Wecf?retrieveContents=true&contentsEncoding=utf8&dataChunkSize=1024 HTTP/1.1
X-BCoT-Timestamp: 20220818T125045Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220818/ctn1_request, Signature=dfc497904304fa61e360940464b4d5a00006297578c1b40abffaf2393fd2fae0
Host: localhost:3000
Connection: close
User-Agent: Paw/3.3.6 (Macintosh; OS X/12.5.1) GCDHTTPRequest
curl "http://localhost:3000/api/0.13/assets/non-fungible/tokens/t76Yzrbqcjbtehk6Wecf?retrieveContents=true&contentsEncoding=utf8&dataChunkSize=1024" \
-H 'X-BCoT-Timestamp: 20220818T125045Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220818/ctn1_request, Signature=dfc497904304fa61e360940464b4d5a00006297578c1b40abffaf2393fd2fae0'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var tokenId = 't76Yzrbqcjbtehk6Wecf';
ctnApiClient.retrieveNonFungibleToken(tokenId, {
retrieveContents: true,
contentsEncoding: 'utf8',
dataChunkSize: 1024
},
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Non-fungible token data:', data);
if (data.continuationToken) {
// Continue retrieving token's contents
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var tokenId = 't76Yzrbqcjbtehk6Wecf';
ctnApiClient.retrieveNonFungibleToken(tokenId, {
retrieveContents: true,
contentsEncoding: 'utf8',
dataChunkSize: 1024
},
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Non-fungible token data:', data);
if (data.continuationToken) {
// Continue retrieving token's contents
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$tokenId = 't76Yzrbqcjbtehk6Wecf';
try {
$data = $ctnApiClient->retrieveNonFungibleToken($tokenId, [
'retrieveContents' => true,
'contentsEncoding' => 'utf8',
'dataChunkSize' => 1024
]);
// Process returned data
echo 'Non-fungible token data: ' . print_r($data, true);
if (isset($data->continuationToken)) {
// Continue retrieving token's contents
}
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let token_id = "tDGQpGy627J6uAw4grYq";
let result = ctn_client.retrieve_non_fungible_token(token_id, Some(RetrieveNonFungibleTokenOptions {
retrieve_contents: Some(true),
contents_only: None,
contents_encoding: Some(Encoding::UTF8),
data_chunk_size: Some(1024),
async_: None,
continuation_token: None,
}))?;
println!("Non-fungible token data: {:?}", result);
if result.continuation_token.is_some() {
// Continue retrieving token's contents
}
Ok(())
}
Accessibility
Private
Request
GET /assets/non-fungible/tokens/:tokenId
Parameters
URL parameters:
tokenId
: The ID of the non-fungible token the data of which should be retrieved.
Query string parameters:
retrieveContents
: (optional, default:true
; should be omitted in a continuation call) A boolean value indicating whether the contents of the non-fungible token should be retrieved or not.contentsOnly
: (optional, default:false
; should be omitted in a continuation call) A boolean value indicating whether only the contents of the non-fungible token should be retrieved.contentsEncoding
: (optional, default:base64
; should be omitted in a continuation call) The encoding with which the retrieved chunk of non-fungible token contents data will be encoded. Valid values:utf8
,base64
,hex
.dataChunkSize
: (optional; should be omitted in a continuation call) Numeric value representing the size, in bytes, of the largest chunk of non-fungible token contents data that should be returned.async
: (optional, default:false
; should be omitted in a continuation call) A boolean value indicating whether the processing should be done asynchronously.continuationToken
: (optional; should be included only in a continuation call) This signals a continuation call of the non-fungible token retrieval. It should be filled with the continuation token returned by the previous call.
Sample response:
{
"status": "success",
"data": {
"nonFungibleToken": {
"assetId": "ahfTzqgWAXnMR6Z57mcp",
"metadata": {
"name": "NFA9 NFT 2",
"description": "Second token of Catenis non-fungible asset #9",
"contentsEncrypted": true,
"contentsURL": "http://localhost:8080/ipfs/QmR5RGXM3KJrYoe958UXuaL2TXt24ga53xKZvqaY2pDeZ1"
},
"contents": {
"data": "Here is the contents of the second token of Catenis non-fungible asset #9 (part #1); and here is the last part of the contents of the second token of Catenis non-fungible asset #9."
}
}
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
continuationToken |
String | (only returned if there is more data to be retrieved) The continuation token to be used in the next continuation call. |
tokenRetrievalId |
String | (only returned for the initial call when doing processing asynchronously) The token retrieval ID. Used for retrieving the progress of an asynchronous non-fungible token retrieval. |
nonFungibleToken |
Object | (not returned for the initial call when doing processing asynchronously) The retrieved non-fungible token data. |
assetId |
String | (not returned for a continuation call or when retrieving only the contents) The ID of the non-fungible asset to which the non-fungible token belongs. |
metadata |
Object | (not returned for a continuation call or when retrieving only the contents) The non-fungible token metadata. |
name |
String | The name of the non-fungible token. |
description |
String | (only returned if present) A description of the non-fungible token. |
contentsEncrypted |
Boolean | Indicates whether the stored contents is encrypted. |
contentsURL |
String | URL pointing to the non-fungible token's contents stored on IPFS. |
custom |
Object | (only returned if present) User defined, custom properties of the non-fungible token. |
sensitiveProps |
Object | (only returned if present) User defined, sensitive properties of the non-fungible token. Sensitive properties are stored in an encrypted form. |
<prop_name> |
* | A custom, sensitive property identified by prop_name . |
<prop_name> |
* | A custom property identified by prop_name . |
contents |
Object | (not returned when the contents should not be retrieved) The retrieved non-fungible token contents data. |
data |
String | The text encoded non-fungible token contents data. |
Possible errors
Retrieve Non-Fungible Token Retrieval Progress
Retrieves the current progress of an asynchronous non-fungible token retrieval.
Sample request:
GET /api/0.13/assets/non-fungible/tokens/t76Yzrbqcjbtehk6Wecf/retrieval/ret28tCLCFaWipyCCEEL HTTP/1.1
X-BCoT-Timestamp: 20220818T135253Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220818/ctn1_request, Signature=4c6fa9cc139bcb00b625bd31377dff3b7610ef0c3ac37582f94361e7184e2c49
Host: localhost:3000
Connection: close
User-Agent: Paw/3.3.6 (Macintosh; OS X/12.5.1) GCDHTTPRequest
curl "http://localhost:3000/api/0.13/assets/non-fungible/tokens/t76Yzrbqcjbtehk6Wecf/retrieval/ret28tCLCFaWipyCCEEL" \
-H 'X-BCoT-Timestamp: 20220818T135253Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220818/ctn1_request, Signature=4c6fa9cc139bcb00b625bd31377dff3b7610ef0c3ac37582f94361e7184e2c49'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var tokenId = 't76Yzrbqcjbtehk6Wecf';
var retrievalId = 'ret28tCLCFaWipyCCEEL';
ctnApiClient.retrieveNonFungibleTokenRetrievalProgress(tokenId, retrievalId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Bytes already retrieved:', data.progress.bytesRetrieved);
if (data.progress.done) {
if (data.progress.success) {
// Display result...
console.log('Continuation token:', data.continuationToken);
// and finish retrieving the non-fungible token data
}
else {
// Process error
console.error('Asynchronous processing error: [', data.progress.error.code, ' ] -', data.progress.error.message);
}
}
else {
// Asynchronous processing not done yet. Continue pooling
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var tokenId = 't76Yzrbqcjbtehk6Wecf';
var retrievalId = 'ret28tCLCFaWipyCCEEL';
ctnApiClient.retrieveNonFungibleTokenRetrievalProgress(tokenId, retrievalId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Bytes already retrieved:', data.progress.bytesRetrieved);
if (data.progress.done) {
if (data.progress.success) {
// Display result...
console.log('Continuation token:', data.continuationToken);
// and finish retrieving the non-fungible token data
}
else {
// Process error
console.error('Asynchronous processing error: [', data.progress.error.code, ' ] -', data.progress.error.message);
}
}
else {
// Asynchronous processing not done yet. Continue pooling
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$tokenId = 't76Yzrbqcjbtehk6Wecf';
$retrievalId = 'ret28tCLCFaWipyCCEEL';
try {
$data = $ctnApiClient->retrieveNonFungibleTokenRetrievalProgress($tokenId, $retrievalId);
// Process returned data
echo 'Bytes already retrieved: ', $data->progress->bytesRetrieved . PHP_EOL;
if ($data->progress->done) {
if ($data->progress->success) {
// Display result...
echo 'Continuation token: ' . $data->continuationToken . PHP_EOL;
// and finish retrieving the non-fungible token data
} else {
// Process error
echo 'Asynchronous processing error: [' . $data->progress->error->code . '] - '
. $data->progress->error->message . PHP_EOL;
}
} else {
// Asynchronous processing not done yet. Continue pooling
}
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let token_id = "t76Yzrbqcjbtehk6Wecf";
let retrieval_id = "ret28tCLCFaWipyCCEEL";
let result = ctn_client.retrieve_non_fungible_token_retrieval_progress(token_id, retrieval_id)?;
println!("Bytes already retrieved: {}", result.progress.bytes_retrieved.to_string());
if result.progress.done {
if let Some(true) = result.progress.success {
// Display result...
println!("Continuation token: {}", result.continuation_token.unwrap());
// and finish retrieving the non-fungible token data
} else {
// Process error
let error = result.progress.error.unwrap();
println!("Asynchronous processing error: [{}] - {}", error.code, error.message);
}
} else {
// Asynchronous processing not done yet. Continue pooling
}
Ok(())
}
Accessibility
Private
Request
GET /assets/non-fungible/tokens/:tokenId
/retrieval/:retrievalId
Parameters
- URL parameters:
tokenId
: The ID of the non-fungible token whose data is being retrieved.retrievalId
: The ID of the non-fungible token retrieval the processing progress of which should be retrieved.
Sample response:
{
"status": "success",
"data": {
"progress": {
"bytesRetrieved": 512,
"done": true,
"success": true,
"finishDate": "2022-08-18T13:52:15.864Z"
},
"continuationToken": "eQ4YnusDtqm7Mn5Th7aj"
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
progress |
Object | Current processing status. |
bytesRetrieved |
Number | Number of bytes of non-fungible token data that have been retrieved. |
done |
Boolean | Indicates whether the processing has been finished. |
success |
Boolean | (only returned if the processing has already been finished) Indicates whether all the non-fungible token data has been successfully retrieved. |
error |
Object | (only returned if the processing finished with error) Information about the error that took place while retrieving the non-fungible token data. |
code |
Number | Numeric code — equivalent to an HTML status code — of the error. |
message |
String | Text describing the error. |
finishDate |
String | (only returned if the processing has already been finished) ISO 8601 formatted date and time when the data retrieval has been finalized. |
continuationToken |
String | (only returned if the processing finished successfully) The token that should be used to complete the retrieval of the non-fungible token. |
Possible errors
Retrieve Non-Fungible Token Transfer Progress
Retrieves the current progress of an asynchronous non-fungible token transfer.
Sample request:
GET /api/0.13/assets/non-fungible/tokens/ttbG9ia4AjdP5Pm7WaLG/transfer/xBvAEtQmnMH3eQTAbeHx HTTP/1.1
X-BCoT-Timestamp: 20220818T184156Z
Authorization: CTN1-HMAC-SHA256 Credential=d8YpQ7jgPBJEkBrnvp58/20220818/ctn1_request, Signature=c35a6928c680ae2f6674ef9fd6b2743f5783c98185dd8adc8f9cb1d544e0c83b
Host: localhost:3000
Connection: close
User-Agent: Paw/3.3.6 (Macintosh; OS X/12.5.1) GCDHTTPRequest
curl "http://localhost:3000/api/0.13/assets/non-fungible/tokens/ttbG9ia4AjdP5Pm7WaLG/transfer/xBvAEtQmnMH3eQTAbeHx" \
-H 'X-BCoT-Timestamp: 20220818T184156Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=d8YpQ7jgPBJEkBrnvp58/20220818/ctn1_request, Signature=ef114f4eac5789a69b508c38508dcaf03c20adac1817c2a0a3f2715d04996f3b'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var tokenId = 'ttbG9ia4AjdP5Pm7WaLG';
var transferId = 'xBvAEtQmnMH3eQTAbeHx';
ctnApiClient.retrieveNonFungibleTokenTransferProgress(tokenId, tokenTransferId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Current data manipulation:', data.progress.dataManipulation);
if (data.progress.done) {
if (data.progress.success) {
// Display result
console.log('Non-fungible token successfully transferred');
}
else {
// Process error
console.error('Asynchronous processing error: [', data.progress.error.code, ' ] -', data.progress.error.message);
}
}
else {
// Asynchronous processing not done yet. Continue pooling
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var tokenId = 'ttbG9ia4AjdP5Pm7WaLG';
var transferId = 'xBvAEtQmnMH3eQTAbeHx';
ctnApiClient.retrieveNonFungibleTokenTransferProgress(tokenId, tokenTransferId,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Current data manipulation:', data.progress.dataManipulation);
if (data.progress.done) {
if (data.progress.success) {
// Display result
console.log('Non-fungible token successfully transferred');
}
else {
// Process error
console.error('Asynchronous processing error: [', data.progress.error.code, ' ] -', data.progress.error.message);
}
}
else {
// Asynchronous processing not done yet. Continue pooling
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$tokenId = 'ttbG9ia4AjdP5Pm7WaLG';
$transferId = 'xBvAEtQmnMH3eQTAbeHx';
try {
$data = $ctnApiClient->retrieveNonFungibleTokenTransferProgress($tokenId, $transferId);
// Process returned data
echo 'Current data manipulation: ', print_r($data->progress->dataManipulation, true);
if ($data->progress->done) {
if ($data->progress->success) {
// Display result
echo 'Non-fungible token successfully transferred' . PHP_EOL;
} else {
// Process error
echo 'Asynchronous processing error: [' . $data->progress->error->code . '] - '
. $data->progress->error->message . PHP_EOL;
}
} else {
// Asynchronous processing not done yet. Continue pooling
}
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let token_id = "ttbG9ia4AjdP5Pm7WaLG";
let transfer_id = "xBvAEtQmnMH3eQTAbeHx";
let result = ctn_client.retrieve_non_fungible_token_transfer_progress(token_id, transfer_id)?;
println!("Current data manipulation: {:?}", result.progress.data_manipulation);
if result.progress.done {
if let Some(true) = result.progress.success {
// Display result
println!("Non-fungible token successfully transferred");
} else {
// Process error
let error = result.progress.error.unwrap();
println!("Asynchronous processing error: [{}] - {}", error.code, error.message);
}
} else {
// Asynchronous processing not done yet. Continue pooling
}
Ok(())
}
Accessibility
Private
Request
GET /assets/non-fungible/tokens/:tokenId
/transfer/:transferId
Parameters
- URL parameters:
tokenId
: The ID of the non-fungible token that is being transferred.transferId
: The ID of the non-fungible token transfer the processing progress of which should be retrieved.
Sample response:
{
"status": "success",
"data": {
"progress": {
"dataManipulation": {
"bytesRead": 398,
"bytesWritten": 472
},
"done": true,
"success": true,
"finishDate": "2022-08-18T18:41:31.933Z"
}
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
progress |
Object | Current processing status. |
dataManipulation |
Object | Progress of the non-fungible token data manipulation: reading and rewriting it after re-encryption (if required). |
bytesRead |
Number | Number of bytes of non-fungible token data that have been read. |
bytesWritten |
Number | (only returned if data needed to be re-encrypted) Number of bytes of non-fungible token data that have been written. |
done |
Boolean | Indicates whether the processing has been finished. |
success |
Boolean | (only returned if the processing has already been finished) Indicates whether the non-fungible token has been successfully transferred. |
error |
Object | (only returned if the processing finished with error) Information about the error that took place while transferring the non-fungible token. |
code |
Number | Numeric code — equivalent to an HTML status code — of the error. |
message |
String | Text describing the error. |
finishDate |
String | (only returned if the processing has already been finished) ISO 8601 formatted date and time when the non-fungible token transfer has been finalized. |
Possible errors
Retrieve Permission Rights
Gets the permission rights currently set for a specific permission event.
The virtual device issuing the request acts as the controlling device. Thus the permission rights to be retrieved are the ones set for the pair composed of the permission event specified in the API request and the virtual device issuing the request.
Sample request:
GET /api/0.13/permission/events/receive-msg/rights HTTP/1.1
X-BCoT-Timestamp: 20180217T193337Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=b6bf27017c8ee92da349f80e27e127f3c2cb3adeeeee28e19c18d9b9c3b752a8
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
curl "https://sandbox.catenis.io/api/0.13/permission/events/receive-msg/rights" \
-H 'X-BCoT-Timestamp: 20180217T193358Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=6d2748f961de6714c16a0ff9096a9a9c2607778c2dc107d2f7492bc0878d2a81'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.retrievePermissionRights('receive-msg', function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Default (system) permission right:', data.system);
if (data.catenisNode) {
if (data.catenisNode.allow) {
console.log('Index of Catenis nodes with \'allow\' permission right:', data.catenisNode.allow);
}
if (data.catenisNode.deny) {
console.log('Index of Catenis nodes with \'deny\' permission right:', data.catenisNode.deny);
}
}
if (data.client) {
if (data.client.allow) {
console.log('ID of clients with \'allow\' permission right:', data.client.allow);
}
if (data.client.deny) {
console.log('ID of clients with \'deny\' permission right:', data.client.deny);
}
}
if (data.device) {
if (data.device.allow) {
console.log('Devices with \'allow\' permission right:', data.device.allow);
}
if (data.device.deny) {
console.log('Devices with \'deny\' permission right:', data.device.deny);
}
}
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.retrievePermissionRights('receive-msg', function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Default (system) permission right:', data.system);
if (data.catenisNode) {
if (data.catenisNode.allow) {
console.log('Index of Catenis nodes with \'allow\' permission right:', data.catenisNode.allow);
}
if (data.catenisNode.deny) {
console.log('Index of Catenis nodes with \'deny\' permission right:', data.catenisNode.deny);
}
}
if (data.client) {
if (data.client.allow) {
console.log('ID of clients with \'allow\' permission right:', data.client.allow);
}
if (data.client.deny) {
console.log('ID of clients with \'deny\' permission right:', data.client.deny);
}
}
if (data.device) {
if (data.device.allow) {
console.log('Devices with \'allow\' permission right:', data.device.allow);
}
if (data.device.deny) {
console.log('Devices with \'deny\' permission right:', data.device.deny);
}
}
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
try {
$data = $ctnApiClient->retrievePermissionRights('receive-msg');
// Process returned data
echo 'Default (system) permission right: ' . $data->system . PHP_EOL;
if (isset($data->catenisNode)) {
if (isset($data->catenisNode->allow)) {
echo 'Index of Catenis nodes with \'allow\' permission right: ' . implode($data->catenisNode->allow, ', ') . PHP_EOL;
}
if (isset($data->catenisNode->deny)) {
echo 'Index of Catenis nodes with \'deny\' permission right: ' . implode($data->catenisNode->deny, ', ') . PHP_EOL;
}
}
if (isset($data->client)) {
if (isset($data->client->allow)) {
echo 'ID of clients with \'allow\' permission right: ' . implode($data->client->allow, ', ') . PHP_EOL;
}
if (isset($data->client->deny)) {
echo 'ID of clients with \'deny\' permission right: ' . implode($data->client->deny, ', ') . PHP_EOL;
}
}
if (isset($data->device)) {
if (isset($data->device->allow)) {
echo 'Devices with \'allow\' permission right: ' . print_r($data->device->allow, true);
}
if (isset($data->device->deny)) {
echo 'Devices with \'deny\' permission right: ' . print_r($data->device->deny, true);
}
}
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let result = ctn_client.retrieve_permission_rights(
PermissionEvent::ReceiveMsg,
)?;
println!("Default (system) permission right: {:?}", result.system);
if let Some(rights_setting) = result.catenis_node {
if let Some(catenis_node_idxs) = rights_setting.allow {
println!(
"Index of Catenis nodes with 'allow' permission right: {:?}",
catenis_node_idxs
);
}
if let Some(catenis_node_idxs) = rights_setting.deny {
println!(
"Index of Catenis nodes with 'deny' permission right: {:?}",
catenis_node_idxs
);
}
}
if let Some(rights_setting) = result.client {
if let Some(client_ids) = rights_setting.allow {
println!("ID of clients with 'allow' permission right: {:?}", client_ids);
}
if let Some(client_ids) = rights_setting.deny {
println!("ID of clients with 'deny' permission right: {:?}", client_ids);
}
}
if let Some(rights_setting) = result.device {
if let Some(devices) = rights_setting.allow {
println!("Devices with 'allow' permission right: {:?}", devices);
}
if let Some(devices) = rights_setting.deny {
println!("Devices with 'deny' permission right: {:?}", devices);
}
}
Ok(())
}
Accessibility
Private
Request
GET /permission/events/:eventName
/rights
Parameters
- URL parameters:
eventName
: The name of the permission event the permission rights set for which should be retrieved.
Sample response:
{
"status": "success",
"data": {
"system": "deny",
"client": {
"allow": [
"cjNhuvGMUYoepFcRZadP"
]
},
"device": {
"allow": [
{
"deviceId": "dv3htgvK7hjnKx3617Re",
"name": "Catenis device #1"
}
]
}
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
system |
String | Permission right set at the system level. |
catenisNode |
Object | (only returned if there are any permission rights set at the Catenis node level) |
allow |
Array(String) | (only returned if not empty) List of Catenis node indices identifying the Catenis nodes to which allow right has been given. |
deny |
Array(String) | (only returned if not empty) List of Catenis node indices identifying the Catenis nodes to which deny right has been given. |
client |
Object | (only returned if there are any permission rights set at the client level) |
allow |
Array(String) | (only returned if not empty) List of client IDs identifying the clients to which allow right has been given. |
deny |
Array(String) | (only returned if not empty) List of client IDs identifying the clients to which deny right has been given. |
device |
Object | (only returned if there are any permission rights set at the device level) |
allow |
Array(Object) | (only returned if not empty) List of virtual device info objects identifying the devices to which allow right has been given. |
deviceId |
String | The device ID of the virtual device. |
name |
String | (only returned if virtual device has this data, and the virtual device issuing the request has the necessary permission right) The name of the virtual device. |
prodUniqueId |
String | (only returned if virtual device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the virtual device. |
deny |
Array(Object) | (only returned if not empty) List of virtual device info objects identifying the virtual devices to which deny right has been given. |
deviceId |
String | The device ID of the virtual device. |
name |
String | (only returned if virtual device has this data, and the virtual device issuing the request has the necessary permission right) The name of the virtual device. |
prodUniqueId |
String | (only returned if virtual device has this data, and the virtual device issuing the request has the necessary permission right) The product unique ID of the virtual device. |
Possible errors
Status code | Error message |
---|---|
400 | Invalid parameters: <param_list> |
500 | Internal server error |
503 | System currently not available; please try again at a later time |
Send Message
Records a message on the blockchain directing it to another virtual device.
The virtual device that sends the message is referred to as the origin device, and the virtual device to which the message is sent is referred to as the target device.
Sample request:
POST /api/0.13/messages/send HTTP/1.1
X-BCoT-Timestamp: 20200122T200146Z
Authorization: CTN1-HMAC-SHA256 Credential=d8YpQ7jgPBJEkBrnvp58/20200122/ctn1_request, Signature=bb952d55523490deb8dafd2c0f7d7acaf71959026fa844a2fa36de1084d3d54c
Content-Type: application/json; charset=utf-8
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.10 (Macintosh; OS X/10.15.2) GCDHTTPRequest
Content-Length: 180
{"message":"This is only a test","targetDevice":{"id":"dv3htgvK7hjnKx3617Re"},"options":{"encoding":"utf8","encrypt":true,"offChain":true,"storage":"auto","readConfirmation":true}}
curl -X "POST" "http://localhost:3000/api/0.13/messages/send" \
-H 'X-BCoT-Timestamp: 20200122T200220Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=d8YpQ7jgPBJEkBrnvp58/20200122/ctn1_request, Signature=406727fab045ade27eb6fa87012698b542aca4a44b889951dee249b05350b3b9' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"message": "This is only a test",
"options": {
"encoding": "utf8",
"encrypt": true,
"offChain": true,
"storage": "auto",
"readConfirmation": true
},
"targetDevice": {
"id": "dv3htgvK7hjnKx3617Re"
}
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var targetDevice = {
id: 'dv3htgvK7hjnKx3617Re'
}
ctnApiClient.sendMessage('This is only a test', targetDevice, {
encoding: 'utf8',
encrypt: true,
offChain: true,
storage: 'auto',
readConfirmation: true
},
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('ID of sent message:', data.messageId);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var targetDevice = {
id: 'dv3htgvK7hjnKx3617Re'
}
ctnApiClient.sendMessage(targetDevice, 'This is only a test', {
encoding: 'utf8',
encrypt: true,
offChain: true,
storage: 'auto',
readConfirmation: true
},
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('ID of sent message:', data.messageId);
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$targetDevice = [
'id' => 'dv3htgvK7hjnKx3617Re'
];
try {
$data = $ctnApiClient->sendMessage($targetDevice, 'My message to send', [
'encoding' => 'utf8',
'encrypt' => true,
'offChain' => true,
'storage' => 'auto',
'readConfirmation' => true
]);
// Process returned data
echo 'ID of sent message: ' . $data->messageId . PHP_EOL;
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let target_device = DeviceId {
id: String::from("dv3htgvK7hjnKx3617Re"),
is_prod_unique_id: None,
};
let result = ctn_client.send_message(
Message::Whole(String::from("This is only a test")),
target_device,
Some(SendMessageOptions {
encoding: Some(Encoding::UTF8),
encrypt: Some(true),
off_chain: Some(true),
storage: Some(Storage::Auto),
read_confirmation: Some(true),
async_: None,
}),
)?;
println!("ID of sent message: {}", result.message_id.unwrap());
Ok(())
}
Accessibility
Private
Request
POST /messages/send
Parameters
- Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
message |
String|Object | The message to send. If an object is passed instead, it is expected that the message be passed in chunks. |
data |
String | (optional) The next message data chunk. The actual message's contents should be comprised of one or more data chunks. |
isFinal |
Boolean | (optional, default: true ) Indicates whether this is the final message data chunk. |
continuationToken |
String | (optional) Indicates that this is a continuation message data chunk. It should be filled with the value returned in the continuationToken field of the response to the request used to pass the previous message data chunk. |
targetDevice |
Object | |
id |
String | The ID of the virtual device to which the message is directed. Should be a device ID unless isProdUniqueId is set. |
isProdUniqueId |
Boolean | (optional, default: false ) Indicates whether the supplied ID is a product unique ID. |
options |
Object | (optional) |
encoding |
String | (optional, default: utf8 ) Value identifying the encoding of the message. Valid options: utf8 , base64 , hex . |
encrypt |
Boolean | (optional, default: true ) Indicates whether message should be encrypted before storing it. |
offChain |
Boolean | (optional, default: true ) Indicates whether message should be sent as a Catenis off-chain message. |
storage |
String | (optional, default: auto ) Value identifying where the message should be stored. Valid options: auto , embedded , external . The value embedded specifies that the message should be stored on the blockchain transaction itself; the value external specifies that the message should be stored in an external repository; and the value auto is used to specify that the message be embedded whenever possible otherwise it should be stored in the external storage. |
readConfirmation |
Boolean | (optional, default: false ) Indicates whether message should be sent with read confirmation enabled. This should be used when the origin device intends to be notified when the target device first reads the message. |
async |
Boolean | (optional, default: false ) Indicates whether processing — storage of message to the blockchain — should be done asynchronously. |
Sample response:
{
"status": "success",
"data": {
"messageId": "ouczbRbcgo3F8XoC6ejE"
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
continuationToken |
String | (only returned if passing message in chunks and last message data chunk was not final) Token to be used when sending the following message data chunk. |
messageId |
String | (only returned after message has been processed) ID of the sent message. |
provisionalMessageId |
String | (only returned if doing asynchronous processing after the whole message's contents are passed) ID of provisional message. |
Possible errors
Set Permission Rights
Sets permission rights at different levels for a specific permission event.
The virtual device issuing the request acts as the controlling device. Thus the permission rights are set for the pair composed of the permission event specified in the API request and the virtual device issuing the request.
Sample request:
POST /api/0.13/permission/events/receive-msg/rights HTTP/1.1
X-BCoT-Timestamp: 20180217T201833Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=df048c4f799dbc0b15b7b105313b9c134d499eb330ecf1ee2b27b5319c89bb86
Content-Type: application/json; charset=utf-8
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.3) GCDHTTPRequest
Content-Length: 147
{"client":{"allow":"self","deny":"cjNhuvGMUYoepFcRZadP"},"device":{"allow":[{"id":"dv3htgvK7hjnKx3617Re"},{"id":"XYZ0001","isProdUniqueId":true}]}}
curl -X "POST" "https://sandbox.catenis.io/api/0.13/permission/events/receive-msg/rights" \
-H 'X-BCoT-Timestamp: 20180217T201855Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180217/ctn1_request, Signature=d52d99ab524ee9f6ed7ca4d96c0041ff9ba7ca1540497dc527c51596da98a27a' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"client": {
"allow": "self",
"deny": "cjNhuvGMUYoepFcRZadP"
},
"device": {
"allow": [
{
"id": "dv3htgvK7hjnKx3617Re"
},
{
"id": "XYZ0001",
"isProdUniqueId": true
}
]
}
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.setPermissionRights('receive-msg', {
client: {
allow: 'self'
deny: 'cjNhuvGMUYoepFcRZadP'
},
device: {
allow: [{
id: 'dv3htgvK7hjnKx3617Re'
}, {
id: 'XYZ0001',
isProdUniqueId: true
}]
}
},
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Permission rights successfully set');
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
ctnApiClient.setPermissionRights('receive-msg', {
client: {
allow: 'self'
deny: 'cjNhuvGMUYoepFcRZadP'
},
device: {
allow: [{
id: 'dv3htgvK7hjnKx3617Re'
}, {
id: 'XYZ0001',
isProdUniqueId: true
}]
}
},
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Permission rights successfully set');
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
try {
$data = $ctnApiClient->setPermissionRights('receive-msg', [
'client' => [
'allow' => 'self',
'deny' => 'cjNhuvGMUYoepFcRZadP'
],
'device' => [
'allow' => [[
'id' => 'dv3htgvK7hjnKx3617Re'
], [
'id' => 'XYZ0001',
'isProdUniqueId' => true
]]
]
]);
// Process returned data
echo 'Permission rights successfully set' . PHP_EOL;
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let _result = ctn_client.set_permission_rights(
PermissionEvent::ReceiveMsg,
AllPermissionRightsUpdate {
system: None,
catenis_node: None,
client: Some(PermissionRightsUpdate {
allow: Some(vec![
String::from("self"),
]),
deny: Some(vec![
String::from("cjNhuvGMUYoepFcRZadP"),
]),
none: None,
}),
device: Some(DevicePermissionRightsUpdate {
allow: Some(vec![
DeviceId {
id: String::from("dv3htgvK7hjnKx3617Re"),
is_prod_unique_id: None,
},
DeviceId {
id: String::from("XYZ0001"),
is_prod_unique_id: Some(true),
},
]),
deny: None,
none: None,
}),
},
)?;
println!("Permission rights successfully set");
Ok(())
}
Accessibility
Private
Request
POST /permission/events/:eventName
/rights
Parameters
URL parameters:
eventName
: The name of the permission event for which the permission rights should be set.
Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
system |
String | (optional) Permission right to be set at the system level. Valid options: allow , deny . |
catenisNode |
Object | (optional) Permission rights to be set at the Catenis node level. |
allow |
String|Array(String) | (optional) A single Catenis node index or a list of Catenis node indices identifying the Catenis nodes to which allow right should be given. The special value self can be used in place of the index of the Catenis node where the client to which the virtual device issuing the request belongs is defined. |
deny |
String|Array(String) | (optional) A single Catenis node index or a list of Catenis node indices identifying the Catenis nodes to which deny right should be given. The special value self can be used in place of the index of the Catenis node where the client to which the virtual device issuing the request belongs is defined. |
none |
String|Array(String) | (optional) A single Catenis node index or a list of Catenis node indices identifying the Catenis nodes the rights of which should be removed. The special value self can be used in place of the index of the Catenis node where the client to which the virtual device issuing the request belongs is defined. The special wildcard character * can also be used to indicate that the rights for all Catenis nodes should be remove. |
client |
Object | (optional) Permission rights to be set at the client level. |
allow |
String|Array(String) | (optional) A single client ID or a list of client IDs identifying the clients to which allow right should be given. The special value self can be used in place of the client ID of the client to which the virtual device issuing the request belongs. |
deny |
String|Array(String) | (optional) A single client ID or a list of client IDs identifying the clients to which deny right should be given. The special value self can be used in place of the client ID of the client to which the virtual device issuing the request belongs. |
none |
String|Array(String) | (optional) A single client ID or a list of client IDs identifying the clients the rights of which should be removed. The special value self can be used in place of the client ID of the client to which the virtual device issuing the request belongs. The special wildcard character * can also be used to indicate that the rights for all clients should be remove. |
device |
Object | (optional) Permission rights to be set at the device level. |
allow |
Object|Array(Object) | (optional) A single virtual device info object or a list of virtual device info objects identifying the virtual devices to which allow right should be given. |
id |
String | (optional) The ID of the virtual device. Should be a device ID unless isProdUniqueId is set. The special value self can be used in place of the device ID of the virtual device issuing the request. |
isProdUniqueId |
Boolean | (optional, default: false ) Indicates whether the supplied ID is a product unique ID. |
deny |
Object|Array(Object) | (optional) A single virtual device info object or a list of virtual device info objects identifying the virtual devices to which deny right should be given. |
id |
String | (optional) The ID of the virtual device. Should be a device ID unless isProdUniqueId is set. The special value self can be used in place of the device ID of the virtual device issuing the request. |
isProdUniqueId |
Boolean | (optional, default: false ) Indicates whether the supplied ID is a product unique ID. |
none |
Object|Array(Object) | (optional) A single virtual device info object or a list of virtual device info objects identifying the virtual devices the rights of which should be removed. |
id |
String | (optional) The ID of the virtual device. Should be a device ID unless isProdUniqueId is set. The special value self can be used in place of the device ID of the virtual device issuing the request. The special wildcard character * can also be used to indicate that the rights for all devices should be remove. |
isProdUniqueId |
Boolean | (optional, default: false ) Indicates whether the supplied ID is a product unique ID. |
Sample response:
{
"status": "success",
"data": {
"success": true
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
success |
Boolean | The value true indicating that the permission rights have been correctly set. |
Possible errors
Transfer Asset
Transfers an amount of an asset to a device.
Sample request:
POST /api/0.13/assets/aQjlzShmrnEZeeYBZihc/transfer/ HTTP/1.1
X-BCoT-Timestamp: 20180417T132059Z
Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=44e21bb5c895eceafce0910a27d0879e3be7dcff278c07a01597f09e6c0bb317
Content-Type: application/json; charset=utf-8
Host: sandbox.catenis.io
Connection: close
User-Agent: Paw/3.1.5 (Macintosh; OS X/10.13.4) GCDHTTPRequest
Content-Length: 64
{"amount":54.25,"receivingDevice":{"id":"dv3htgvK7hjnKx3617Re"}}
curl -X "POST" "https://sandbox.catenis.io/api/0.13/assets/aQjlzShmrnEZeeYBZihc/transfer/" \
-H 'X-BCoT-Timestamp: 20180417T132027Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=dnN3Ea43bhMTHtTvpytS/20180417/ctn1_request, Signature=17bb4e914bd10aa517d15df1c985f0e9604a660a3a146219e16a1c94a8f7bf93' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"amount": 54.25,
"receivingDevice": {
"id": "dv3htgvK7hjnKx3617Re"
}
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aQjlzShmrnEZeeYBZihc';
var receivingDevice = {
id: 'dv3htgvK7hjnKx3617Re'
};
ctnApiClient.transferAsset(assetId, 54.25, receivingDevice,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Remaining asset balance:', data.remainingBalance);
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var assetId = 'aQjlzShmrnEZeeYBZihc';
var receivingDevice = {
id: 'dv3htgvK7hjnKx3617Re'
};
ctnApiClient.transferAsset(assetId, 54.25, receivingDevice,
function (err, data) {
if (err) {
// Process error
}
else {
// Process returned data
console.log('Remaining asset balance:', data.remainingBalance);
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$assetId = 'aQjlzShmrnEZeeYBZihc';
$receivingDevice = [
'id' => 'dv3htgvK7hjnKx3617Re'
];
try {
$data = $ctnApiClient->transferAsset($assetId, 54.25, $receivingDevice);
// Process returned data
echo 'Remaining asset balance: ' . $data->remainingBalance . PHP_EOL;
}
catch (CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let asset_id = "aQjlzShmrnEZeeYBZihc";
let receiving_device = DeviceId {
id: String::from("dv3htgvK7hjnKx3617Re"),
is_prod_unique_id: None,
};
let result = ctn_client.transfer_asset(
asset_id,
54.25,
receiving_device,
)?;
println!("Remaining asset balance: {}", result.remaining_balance);
Ok(())
}
Accessibility
Private
Request
POST /assets/:assetId
/transfer
Parameters
URL parameters:
assetId
: The ID of the asset to transfer an amount of it.
Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
amount |
Number | The amount of asset to transfer. |
receivingDevice |
Object | Virtual device to which the asset is to be transferred. |
id |
String | The ID of the receiving device. Should be a device ID unless isProdUniqueId is set. |
isProdUniqueId |
Boolean | (optional, default: false ) Indicates whether the supplied ID is a product unique ID. |
Sample response:
{
"status": "success",
"data": {
"remainingBalance": 1145.75
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
remainingBalance |
Number | Total balance of the asset still held by the device that issued the request after the transfer. |
Possible errors
Transfer Non-Fungible Token
Transfers a non-fungible token to a virtual device.
Sample request:
POST /api/0.13/assets/non-fungible/tokens/ttbG9ia4AjdP5Pm7WaLG/transfer HTTP/1.1
X-BCoT-Timestamp: 20220818T143907Z
Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220818/ctn1_request, Signature=025ddf3aa2246de4e67f61635e68b52fb7f042ad8be780866690f4760430124e
Content-Type: application/json; charset=utf-8
Host: localhost:3000
Connection: close
User-Agent: Paw/3.3.6 (Macintosh; OS X/12.5.1) GCDHTTPRequest
Content-Length: 49
{"receivingDevice":{"id":"d8YpQ7jgPBJEkBrnvp58"}}
curl -X "POST" "http://localhost:3000/api/0.13/assets/non-fungible/tokens/ttbG9ia4AjdP5Pm7WaLG/transfer" \
-H 'X-BCoT-Timestamp: 20220818T143907Z' \
-H 'Authorization: CTN1-HMAC-SHA256 Credential=drc3XdxNtzoucpw9xiRp/20220818/ctn1_request, Signature=025ddf3aa2246de4e67f61635e68b52fb7f042ad8be780866690f4760430124e' \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"receivingDevice": {
"id": "d8YpQ7jgPBJEkBrnvp58"
}
}'
<script src="CatenisAPIClientJS.min.js"></script>
<script language="JavaScript">
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var tokenId = 'ttbG9ia4AjdP5Pm7WaLG';
var receivingDevice = {
id: 'd8YpQ7jgPBJEkBrnvp58'
};
ctnApiClient.transferNonFungibleToken(tokenId, receivingDevice,
function (err, data) {
if (err) {
// Process error
}
else {
// Display result
console.log('Non-fungible token successfully transferred');
}
});
</script>
var CtnApiClient = require('catenis-api-client');
var deviceId = 'dnN3Ea43bhMTHtTvpytS';
var ctnApiClient = new CtnApiClient(deviceId, apiAccessSecret, {
environment: 'sandbox'
});
var tokenId = 'ttbG9ia4AjdP5Pm7WaLG';
var receivingDevice = {
id: 'd8YpQ7jgPBJEkBrnvp58'
};
ctnApiClient.transferNonFungibleToken(tokenId, receivingDevice,
function (err, data) {
if (err) {
// Process error
}
else {
// Display result
console.log('Non-fungible token successfully transferred');
}
});
<?php
require __DIR__ . '/vendor/autoload.php';
use Catenis\ApiClient;
use Catenis\Exception\CatenisException;
$deviceId = 'dnN3Ea43bhMTHtTvpytS';
$ctnApiClient = new ApiClient($deviceId, $apiAccessSecret, [
'environment' => 'sandbox'
]);
$tokenId = 'ttbG9ia4AjdP5Pm7WaLG';
$receivingDevice = [
'id' => 'd8YpQ7jgPBJEkBrnvp58'
];
try {
$ctnApiClient->transferNonFungibleToken($tokenId, $receivingDevice);
// Display result
echo 'Non-fungible token successfully transferred' . PHP_EOL;
} catch (\Catenis\Exception\CatenisException $ex) {
// Process exception
}
use catenis_api_client::{
CatenisClient, ClientOptions, Environment, Result,
api::*,
};
fn main() -> Result<()> {
let device_credentials = (
"dnN3Ea43bhMTHtTvpytS",
concat!(
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
),
).into();
let mut ctn_client = CatenisClient::new_with_options(
Some(device_credentials),
&[
ClientOptions::Environment(Environment::Sandbox),
],
)?;
let token_id = "ttbG9ia4AjdP5Pm7WaLG";
let receiving_device = DeviceId {
id: String::from("d8YpQ7jgPBJEkBrnvp58"),
is_prod_unique_id: None,
};
ctn_client.transfer_non_fungible_token(token_id, receiving_device, None)?;
println!("Non-fungible token successfully transferred");
Ok(())
}
Accessibility
Private
Request
POST /assets/non-fungible/tokens/:tokenId
/transfer
Parameters
URL parameters:
tokenId
: The ID of the non-fungible token to transfer.
Request body:
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
receivingDevice |
Object | Virtual device to which the non-fungible token is to be transferred. |
id |
String | The ID of the receiving device. Should be a device ID unless isProdUniqueId is set. |
isProdUniqueId |
Boolean | (optional, default: false ) Indicates whether the supplied ID is a product unique ID. |
async |
Boolean | (optional, default: false ) Indicates whether processing should be done asynchronously. |
Sample response:
{
"status": "success",
"data": {
"success": true
}
}
Success response
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
status |
String | The value success , indicating that the request was successful. |
data |
Object | The actual data returned in response to the API request. |
tokenTransferId |
String | (only returned when doing processing asynchronously) The non-fungible token transfer ID. Used for retrieving the progress of an asynchronous non-fungible token transfer. |
success |
Boolean | (not returned when doing processing asynchronously) The value true , indicating that the non-fungible token has been successfully transferred. |
Possible errors
Notifications
Catenis provides a notification service where a virtual device can receive a real-time message notifying that a given predefined event that concerns it has taken place. Such predefined events are referred to as notification events.
Notification events
The following notification events are currently defined:
Event name | Description |
---|---|
new-msg-received |
A new message has been received |
sent-msg-read |
Previously sent message has been read by intended receiver (target device) |
asset-received |
An amount of an asset has been received |
asset-confirmed |
An amount of an asset that was pending due to an asset transfer has been confirmed |
final-msg-progress |
Progress of asynchronous message processing has come to an end |
asset-export-outcome |
Asset export has been finalized |
asset-migration-outcome |
Asset migration has been finalized |
nf-asset-issuance-outcome |
Non-fungible asset issuance has been finalized |
nf-token-received |
One or more non-fungible tokens have been received |
nf-token-confirmed |
One or more non-fungible tokens that were pending due to a non-fungible token transfer has been confirmed |
nf-token-retrieval-outcome |
Non-fungible token retrieval has been finalized |
nf-token-transfer-outcome |
Non-fungible token transfer has been finalized |
Notification messages
The Catenis notifications are conveyed by means of notification messages the contents of which vary according to the notification event, as follows:
New message received (new-msg-received)
Sample notification message:
{
"messageId": "mNEWqgSMAeDAmBAkBDWr",
"from": {
"deviceId": "dnN3Ea43bhMTHtTvpytS",
"name": "deviceB",
"prodUniqueId": "XYZABC001"
},
"receivedDate": "2018-01-29T23:27:39.657Z"
}
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
messageId |
String | The ID of the received message. |
from |
Object | Identifies the virtual device that sent the received message — the origin device. |
deviceId |
String | The device ID of the origin device. |
name |
String | (only returned if origin device has this data, and the device receiving the notification has the necessary permission right) The name of the origin device. |
prodUniqueId |
String | (only returned if origin device has this data, and the device receiving the notification has the necessary permission right) The product unique ID of the origin device. |
receivedDate |
String | ISO 8601 formatted date and time when the message has been received. |
Sent message read (sent-msg-read)
Sample notification message:
{
"messageId": "mNEWqgSMAeDAmBAkBDWr",
"to": {
"deviceId": "dv3htgvK7hjnKx3617Re",
"name": "Catenis device #1"
},
"readDate": "2018-01-30T01:02:12.162Z"
}
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
messageId |
String | The ID of the read message. |
to |
Object | Identifies the virtual device to which the read message had been sent — the target device. |
deviceId |
String | The device ID of the target device. |
name |
String | (only returned if target device has this data, and the device receiving the notification has the necessary permission right) The name of the target device. |
prodUniqueId |
String | (only returned if target device has this data, and the device receiving the notification has the necessary permission right) The product unique ID of the target device. |
readDate |
String | ISO 8601 formatted date and time when the message has been read. |
Asset amount received (asset-received)
Sample notification message:
{
"assetId": "aQjlzShmrnEZeeYBZihc",
"issuer": {
"deviceId": "dnN3Ea43bhMTHtTvpytS",
"name": "deviceB",
"prodUniqueId": "XYZABC001"
},
"from": {
"deviceId": "dv3htgvK7hjnKx3617Re",
"name": "Catenis device #1"
},
"receivedDate": "2018-04-01T17:15:36.134Z"
}
A JSON containing the following properties:
Property | Type | Description |
---|---|---|
assetId |
String | The ID of the received asset. |
amount |
Amount | The amount of the asset that has been received. |
issuer |
Object | Identifies the virtual device that issued the asset — the issuing device. |
deviceId |
String | The device ID of the issuing device. |
name |
String | (only returned if issuing device has this data, and the device receiving the notification has the necessary permission right) The name of the issuing device. |
prodUniqueId |
String | (only returned if issuing device has this data, and the device receiving the notification has the necessary permission right) The product unique ID of the issuing device. |
from |
Object | Identifies the virtual device that sent or assigned the asset amount — the sending device. |
deviceId |
String | The device ID of the sending device. |
name |
String | (only returned if sending device has this data, and the device receiving the notification has the necessary permission right) The name of the sending device. |
prodUniqueId |
String | (only returned if sending device has this data, and the device receiving the notification has the necessary permission right) The product unique ID of the sending device. |
receivedDate |
String | ISO 8601 formatted date and time when the asset amount has been received. |
Asset amount confirmed (asset-confirmed)
Sample notification message:
{
"assetId": "aQjlzShmrnEZeeYBZihc",
"amount": 54.25,
"issuer": {
"deviceId": "dnN3Ea43bhMTHtTvpytS",
"name": "deviceB",
"prodUniqueId": "XYZABC001"
},
"from": {
"deviceId": "dv3htgvK7hjnKx3617Re",
"name": "Catenis device #1"
},
"confirmedDate": "2018-04-01T17:32:03.012Z"
}
A JSON containing the following properties:
Property | Type | Description |
---|