Introduction
Sirius is a Digital Assets custody and a blockchain infrastructure API allowing consumers to manage blockchain wallets, keep their assets safe in self-managed custody, flexibly control transaction signing policies, receive deposits and execute withdrawals leveraging omnibus model, deploy and invoke smart contracts, receive smart contract events and read smart contract storage in many different blockchains in a general manner using the same API, data models and management UI. You don't need to learn the particularities of all the blockchains to get into the crypto world and use all top blockchains with ease.
For more information about Sirius, please contact us info@swisschain.io.
Feedback
In the case, if you have found an issue in REST API, gRPC API, Universe portal, or in this documentation, please give us feedback by adding a GitHub issue. Thank you!
V2 requests signing
V2 API supports signed requests with asymmetric cryptography. Since every type of request is structurally different, the format of the data to be signed also varies. In order to sign a request, clientside has to put together a string in the specific format and sign that string with the customer's private key, thereby generating RSA signature. Every V2 API definition contains special-purpose optional field called "Signature", which has to be used to pass the RSA signature to the serverside.
The specific formats of the data to be signed are defined on the respective pages, describing an API endpoint. For clarity, each API endpoint page contains subsection called "Signing data format" with detailed description of the parameters to be used for putting together textual data for signing.
For convenience of use, links to all formats' descriptions are compiled below:
Signing format guidelines
While all requests serve various purposes and therefore consist of different parameters, they also follow several common patterns. The way some of these patterns are used across V2 APIs in relation to the signing functionality is described below:
General format description
Signing data is a sequence of bytes, corresponding to UTF-8-encoded string in the specific format. The beginning and ending
of the signing data are denoted by square brackets: []
. Each parameter value is encased in single quotes: ''
.
Parameters are comma-separated without any whitespace characters before or after the separator.
In the example below there are three parameters, two textual ones and a single numeric parameter:
['parameter Value 1','parameter Value 2','26.7']
Complex parameter values
Complex parameter values such as hashmaps or collections are represented as a single parameter encased with single quotes,
in which several chunks of data may appear separated by a semicolon (;
). In the example below there are two parameters,
first one representing a collection of values and second one is a hashmap:
['1.2;34.0;123.1;12.0','keyOne:valueOne;keyTwo:valueTwo']
Special characters
Since original parameter values may contain special characters, used to encase values or denote boundaries between chunks
of data, their values have to be escaped with a backslash (\
). The comprehensive list of special characters is defined below:
- :
separates key and its corresponding value in hashmaps, escaped as \:
- ;
separates key-value pairs in hashmaps and values in collections, escaped as \;
- '
encases parameter values, escaped as \'
- \
used to escape special characters, escaped as \\
In the example below there are several parameters with special characters in their original values:
['Ocean\'s eleven','keyOne:value\:One;key\;Two:valueTwo','\\path\\to\\directory\\targetFile.txt']
Empty and unset values
Some parameters are optional, but since their position in the signing data format is rigid, it is not possible to simply omit them.
Instead, the absence of its value has to be denoted explicitly with null
without quotes.
In the example below there are two parameters, the first one with value and the second one with value unset:
['Parameter Value One',null]
The absence of a complex parameter value (i.e. when a hashmap parameter is unset) should be treated in the same way.
Numeric values
Parameters with decimal (or BigDecimal) values with or without fractional part have to be formatted with at least one fractional digit. Usually such parameters represent amounts of assets.
Thus, for example 2 has to become 2.0 in the signing data:
['2.0']
Configurable properties
Most API V2 requests support assigning custom properties in the form of set of key-value pairs. Since
assigning properties can change the way request will be handled on the serverside (see known properties),
properties are included in the signing data. Properties normally appear at the very end of signing data format
as a single parameter, encased in single quotes ('
). Properties data is concatenated without any whitespace characters
with colon (:
) as a separator between a key and its corresponding value, and semicolon (;
) as a separator between
key-value pairs. In the signing data format order of properties is important. It is required to sort them alphabetically
by keys.
In the example below there are two regular parameters, followed by four custom properties, sorted by keys alphabetically:
['parameter Value One','124662357832','BrokerageExternalId:445566778899;UserId:12345;UserValidatorId:dr3413;WalletName:TestWallet']
V2 APIs normally accept properties as a hashmap, with key-value pairs in arbitrary order. Received pairs of properties
will be sorted during signature validation internally on the serverside. Following this logic, properties from the example above
can be sent to the serverside in the following way:
json
{
"properties": {
"UserValidatorId": "dr3413",
"WalletName": "TestWallet",
"BrokerageExternalId": "445566778899",
"UserId": 12345
}
}
If the properties are not present at all, it is required to denote their absence with null
similar to any other parameter.
Assets
Sirius provides the set of crypto assets available to use. You can get notifications about a deposit or initiate a withdrawal in any asset presented in this set. The asset is a generic model which represents a native asset, fungible token or a non-fungible token. It's possible that in the different blockchains assets with the same symbol and/or address are existed, so you have to rely only on the asset ID if you need to deterministically identify it. If you've received a deposit of an asset which is not supported by Sirius yet, you can add this particular asset to your personal list by specifying all needed asset parameters.
Rest API: /api/v2/assets
gRPC API: swisschain.sirius.api.v2.assets
Search
Returns assets by search parameters.
gRPC API example: ```csharp var request = new AssetSearchRequest { Id = 10001, BlockchainId = "ethereum", Symbol = "USDC", TokenId = null, Address = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", Accuracy = 6, Pagination = new PaginationInt64 { Cursor = null, Limit = 100, Order = PaginationOrder.Asc } };
var response = client.AssetsV2.SearchAsync(request); ```
REST API example:
json
GET /api/v2/assets?blockchainId=bitcoin&symbol=BTC
Request
REST name | gRPC name | type | description | example |
---|---|---|---|---|
id |
id |
optional, long | ID of the asset to search | 100553 |
blockchainId |
blockchain_id |
optional, string | Exact blockchain id to search | bitcoin-private |
symbol |
symbol |
optional, string | Text to search in the asset symbol | BTC |
tokenId |
token_id |
optional, string | Text to search in the asset symbol | BTC |
address |
address |
optional, string | Exact address to search | 0xC1701AbD559FC263829CA3917d03045F95b5224A |
accuracy |
accuracy |
optional, int | Exact accuracy to search | 8 |
pagination |
--- | optional, Pagination | pagination for gRPC API | |
order |
order |
optional, PaginationOrder, enum | REST Descending or ascending sort of entries | |
limit |
limit |
optional, PaginationLimit, int | REST Maximum number of entries to fetch | |
cursor |
cursor |
optional, PaginationCursor, long | REST ID of anchor entity to start pagination from |
Response
Paginated array of the assets.
Error Code | Meaning |
---|---|
UNKNOWN | An unspecified error code received. |
INVALID_PARAMETERS | Your request contains invalid parameters. |
DOMAIN_PROBLEM | An error occurred while processing request. |
TECHNICAL_PROBLEM | We had a problem with our server. Try again later. |
AddAttributes
Adds asset attributes.
gRPC API example: ```csharp var request = new AssetAddAttributesRequest { IdempotencyId = "AD1D5199-1D1F-4B2C-AE6C-DED0DAAC4D34", AssetId = 10001, Aml = new AmlAssetAttributesCreateInfo { Chainalysis = new AmlChainalysisAssetAttributesInfo { Symbol = "USDC", TransferFormat = ChainalysisTransferFormat.HashAndAddress, IsCheckDepositsEnabled = true, IsCheckWithdrawalsEnabled = true, IsNotifyWithdrawalsEnabled = true }, MerkleScience = new AmlMerkleScienceAssetAttributesInfo { Symbol = "USDC", Currency = 14, IsDisabled = false } }, Brokerage = new BrokerageAssetAttributesCreateInfo { MinDepositThreshold = 1, MinWithdrawalAmount = 1 } };
var response = client.AssetsV2.AddAttributes(request); ```
REST API example: ```json POST /api/v2/assets
Request: (application/json)
Headers:
X-Idempotency-ID: AD1D5199-1D1F-4B2C-AE6C-DED0DAAC4D34Body: { "assetId":123122, "brokerage":{ "minDepositThreshold":9, "minWithdrawalAmount":144 }, "aml":{ "chainalysis":{ "symbol":"MANA", "isCheckWithdrawalsEnabled":true, "isCheckDepositsEnabled":true, "isNotifyWithdrawalsEnabled":true, "transferFormat":"hashAndIndex" }, "merkleScience":{ "symbol":"MANA", "currency":3, "isDisabled":true } } } ```
Request
REST name | gRPC name | type | description | example |
---|---|---|---|---|
X-Idempotency-ID |
--- | string | header | Unique ID of the request |
--- | IdempotencyId |
string | Request unique identifier | "AD1D5199-1D1F-4B2C-AE6C-DED0DAAC4D34" |
assetId |
asset_id |
long | Asset identifier in Sirius | 10001 |
aml |
aml |
AmlAssetAttributesCreateInfo | AML asset attributes | |
brokerage |
brokerage |
BrokerageAssetAttributesCreateInfo | Brokerage asset attributes |
Response
REST name | gRPC name | type | description | example |
---|---|---|---|---|
BrokerageAssetAttributesInfoId |
brokerage_asset_attributes_id |
required long | Brokerage asset attributes identifier | 30002 |
AmlAssetAttributesInfoId |
aml_asset_attributes_id |
long | AML asset attributes identifier | 40002 |
Error Code | Meaning |
---|---|
UNKNOWN | An unspecified error code received. |
INVALID_PARAMETERS | Your request contains invalid parameters. |
DOMAIN_PROBLEM | An error occurred while processing request. |
TECHNICAL_PROBLEM | We had a problem with our server. Try again later. |
Models
Asset
REST name | gRPC name | type | description | example |
---|---|---|---|---|
id |
id |
long | ID of the asset | 100003 |
blockchainId |
blockchain_id |
string | Exact blockchain id | bitcoin-private |
symbol |
symbol |
string | Asset symbol | BTC |
tokenId |
token_id |
string | Token ID | 101 |
address |
address |
string | Exact address | 0xC1701AbD559FC263829CA3917d03045F95b5224A |
accuracy |
accuracy |
int | Exact accuracy | 8 |
name |
name |
string | The name of token | Toy |
metadataUrl |
metadata_url |
string | The token metadata URL | ipfs://metadata.json |
type |
type |
string | The blockchain-specific type of token | ERC-20 |
aml |
aml |
AmlAssetAttributesInfo | The AML attributes | |
brokerage |
brokerage |
BrokerageAssetAttributesInfo | The brokerage attributes |
AmlAssetAttributesCreateInfo
REST name | gRPC name | type | description | example |
---|---|---|---|---|
chainalysis |
chainalysis |
AmlChainalysisAssetAttributesInfo | Chainalysis attributes | |
merkleScience |
merkle_science |
AmlMerkleScienceAssetAttributesInfo | MerkleScience attributes |
AmlAssetAttributesInfo
REST name | gRPC name | type | description | example |
---|---|---|---|---|
id |
id |
long | ID of the info | 300001 |
chainalysis |
chainalysis |
AmlChainalysisAssetAttributesInfo | Chainalysis attributes | |
merkleScience |
merkle_science |
AmlMerkleScienceAssetAttributesInfo | MerkleScience attributes | |
createdAt |
created_at |
DateTime | Create date time | |
updatedAt |
updated_at |
DateTime | Update date time |
AmlChainalysisAssetAttributesInfo
REST name | gRPC name | type | description | example |
---|---|---|---|---|
symbol |
symbol |
string | Chainalysis asset symbol | BTC |
isCheckWithdrawalsEnabled |
is_check_withdrawals_enabled |
bool | Indicates that withdrawals check enabled | true |
isCheckDepositsEnabled |
is_check_deposits_enabled |
bool | Indicates that deposits check enabled | true |
isNotifyWithdrawalsEnabled |
is_notify_withdrawals_enabled |
bool | Indicates that notify withdrawals check enabled | true |
transferFormat |
transfer_format |
ChainalysisTransferFormat | Update date time |
ChainalysisTransferFormat (enum)
HashAndIndex
- Hash and indexHashAndAddress
- Hash and addressHash
- Hash
AmlMerkleScienceAssetAttributesInfo
REST name | gRPC name | type | description | example |
---|---|---|---|---|
symbol |
symbol |
string | MerkleScience asset symbol | BTC |
currency |
currency |
int | MerkleScience currency ID | 12 |
isDisabled |
is_disabled |
bool | Indicates that asset check enabled | true |
BrokerageAssetAttributesCreateInfo
REST name | gRPC name | type | description | example |
---|---|---|---|---|
minDepositThreshold |
min_deposit_threshold |
decimal | Minimum deposit threshold | 0.0001 |
minWithdrawalAmount |
min_withdrawal_amount |
decimal | Minimum withdrawal amount | 0.1 |
BrokerageAssetAttributesInfo
REST name | gRPC name | type | description | example |
---|---|---|---|---|
id |
id |
long | ID of the info | 300001 |
minDepositThreshold |
min_deposit_threshold |
decimal | Minimum deposit threshold | 0.0001 |
minWithdrawalAmount |
min_withdrawal_amount |
decimal | Minimum withdrawal amount | 0.1 |
createdAt |
created_at |
DateTime | Create date time | |
updatedAt |
updated_at |
DateTime | Update date time |
Data structures
TagType (enum)
Tag type of the account. Tag is additional information associated with particular account, which can be specified in the blockchain transaction. This allows to use single blockchain address to handle many accounts on it. This feature is available only on some blockchains: (Ripple, Stellar, Eos...). In some blockchains different types of the tag are supported, and you have to specify exact type in this case.
text
- text tagnumber
- numeric tag
WithdrawalDocument (object)
properties
(map) set of key-value pairs containing custom or known properties assetId
(number) - ID of the asset to usebrokerAccountId
(number) - ID of the broker account to usedestinationDetails
(DestinationDetails) - Destination detailsamount
(decimal) - Withdrawal amount
DestinationDetails (object)
address
(string) withdrawal destination addressdestinationTag
(DestinationTag) - destination tag value and type
DestinationTag (object)
value
(string optional) string value of the tagtagType
(TagType) - type of the tag to use
Withdrawals
Withdrawal refers to outgoing transfers of the funds from a broker account. You can get withdrawals history, or be notified about new withdrawals and state changing of the existing withdrawals. There are different options to be notified about withdrawals state changing:
- You can pull withdrawals updates REST API
- You can listen for withdrawal updates gRPC stream
- You can register a web-hook to get the notifications
Withdrawal can be initiated by you via API or Universe portal UI. Every withdrawal is associated with a broker account, an asset, optionally an account, your internal ID, it has amount, fees and state. You can provide "WalletId" property with the value of account reference ID in order to associate an account to the withdrawal. This link doesn't affect funds flow, it's used just for the reporting and notifying you back with withdrawal updates. Also you can provide "UserId" property with the value of UserNativeId in the users dictionary. This association is optional and can be used to enable AML verification procedure.
The fees required for the withdrawal transaction are paid atop of the specified amount.
The lifecycle of a withdrawal:
Starts a withdrawal
Request
Rest API: POST /api/v2/withdrawals
gRPC API: swisschain.sirius.api.v2.withdrawals.Execute
POST /api/v2/withdrawals
> Request: (application/json)
X-Idempotency-ID: 36585f34-d311-433a-87f1-1751b08480c3
X-TFA-code: 785441
{
"document":{
"properties":{
"WalletId":"12345",
"UserId":"test"
},
"assetId":300578305,
"brokerAccountId":100000140,
"destinationDetails":{
"address":"0x663e933ECdc5b1acbaCB87F4aa1636cd05837613"
},
"amount":0.1
},
"signature":"pqG0st53GVkdBHIqCHsg9cB4noO1nyXlM8UGkZ+bC0fmvCbuf0W78GYj8ZuCtPMWl0XDIh5hVjwsjIPhiUfCl5KVUIA8La3EunRJZ5UkW95IvjcPCn+z5atzb8JQxPee8q2ehaMY+UNH08p1VmIjqJE1eKFzzs8ZxITu0gtwbZ4="
}
swisschain.sirius.api.v2.withdrawals.Execute
> Requests: (application/grpc)
message WithdrawalExecuteRequest {
string idempotency_id = 1; // '36585f34-d311-433a-87f1-1751b08480c3'
WithdrawalDocument document = 2;
bytes signature = 3; // a6 a1 b4 b2 de 77 19 59 1d 04 72 2a 08 7b 20 f5 c0 78 9e 83 b5 9f 25 e5 33 c5 06 91 9f 9b 0b 47 e6 bc 26 ee 7f 45 bb f0 66 23 f1 9b 82 b4 f3 16 97 45 c3 22 1e 61 56 3c 2c 8c 83 e1 89 47 c2 97 92 95 50 80 3c 2d ad c4 ba 74 49 67 95 24 5b de 48 be 37 0f 0a 7f b3 e5 ab 73 6f c2 50 c4 f7 9e f2 ad 9e 85 a3 18 f9 43 47 d3 ca 75 56 62 23 a8 91 35 78 a1 73 ce cf 19 c4 84 ee d2 0b 70 6d 9e
}
message WithdrawalDocument {
map<string,string> properties = 1; // { "WalletId":"12345", "UserId":"test" }
int64 asset_id = 2; // 300578305
int64 broker_account_id = 3; // 100000140
DestinationDetails destination_details = 4;
swisschain.sirius.api.common.BigDecimal amount = 5; // 0.1
}
message DestinationDetails {
string address = 1; // "0x663e933ECdc5b1acbaCB87F4aa1636cd05837613"
DestinationTag destination_tag = 2; // null
}
message DestinationTag {
google.protobuf.StringValue value = 2;
swisschain.sirius.api.common.TagType type = 3;
}
Parameters
REST name | gRPC name | type | REST placement | description |
---|---|---|---|---|
X-Idempotency-ID |
- | string | header | Unique ID of the request |
X-TFA-code |
- | string | header | TFA code |
- | idempotency_id |
string | - | Unique ID of the request |
document |
document |
WithdrawalDocument | body | structured withdrawal parameters |
document.properties |
document.properties |
map |
body | dictionary of key-value pairs with custom or known properties |
document.assetid |
document.asset_id |
int64 | body | ID of the asset to use |
document.brokerAccountId |
document.broker_account_id |
int64 | body | ID of the broker account to use |
document.destinationDetails |
document.destination_details |
DestinationDetails | body | destination parameters of the withdrawal (address and tag info) |
document.Amount |
document.amount |
DestinationDetails | body | destination parameters of the withdrawal (address and tag info) |
signature |
signature |
optional, string | body | Base64-encoded RSA signature of the data signed with the Customer's private key. The exact format of the data to be signed is described below. |
Signing data format
Withdrawal signing data format (order of parameters is important):
['36585f34-d311-433a-87f1-1751b08480c3','300578305','100000140','0x663e933ECdc5b1acbaCB87F4aa1636cd05837613',null,null,'0.1','UserId:test;WalletId:12345']
Parameters used:
0: IdempotencyId 36585f34-d311-433a-87f1-1751b08480c3
1: AssetId 300578305
(BNB)
2: BrokerAccountId 100000140
3: DestinationAddress 0x663e933ECdc5b1acbaCB87F4aa1636cd05837613
4: DestinationTag null
5: DestinationTagType null
6: Amount: 0.1
7: Properties:
7.1: UserId: test
(corresponds to UserNativeId)
7.2: WalletId: 12345
(corresponds to AccountReferenceId)
When putting together signing data, it is required to sort properties alphabetically by keys. However, gRPC and REST APIs accept properties as hashmap of unordered key-value pairs. These key-value pairs will be sorted during signature validation internally on the serverside.
The presented signing data format is used whenever client wishes to execute signed withdrawal. Withdrawal signing data has to be constructed on the client side and signed with customer private key.
Notes on the signing data format:
- Please use null
without quotes for parameters without value (including properties)
- Please format numeric values with at least one fractional digit, even if the value is an integer (i.e. 2 has to become 2.0)
For more information on the signing data format and its usage please refer to the page dedicated to signing data formats.
Response
POST /api/v2/withdrawals
> Response: 200 (application/json) - success response
{
"id":106000003
}
swisschain.sirius.api.withdrawals.Withdrawals.Execute
> Response: (application/grpc) - success response
message WithdrawalExecutePayload {
int64 id = 1;
}
message WithdrawalExecuteError {
enum ErrorCode {
UNKNOWN = 0;
INVALID_PARAMETERS = 1;
DOMAIN_PROBLEM = 2;
TECHNICAL_PROBLEM = 3;
NOT_AUTHORIZED = 4;
NOT_ENOUGH_BALANCE = 5;
}
ErrorCode code = 1;
string message = 2;
}
message WithdrawalExecuteResponse {
oneof result {
WithdrawalExecutePayload payload = 1;
WithdrawalExecuteError error = 2;
}
}
Parameters
REST name | gRPC name | type | REST placement | description |
---|---|---|---|---|
id |
id |
number | ID of the withdrawal |
Known properties
V2 API allows assigning custom properties to some requests in the form of set of key-value pairs where both key and value are strings. Users can provide custom keys or use some known properties with predefined behaviour and functionality.
The list of the known properties and their respective behaviour is defined below:
UserId
: allows passing identifier from the AML verification (formerly known as UserNativeID);WalletId
: allows linking request to specific account, the value is used to look up Account with the specifiedAccountReferenceId