Skip to main content

Mixin Sequencer API

The latest Mixin overall network is based on Mixin Safe, and the network mainly consists of two parts: Mixin Kernel and Mixin Safe. For ease of use, we developed Mixin Sequencer to index and sort all relevant transactions of Kernel, so we will say on the product that it is a new network based on Mixin Safe, but here we mainly introduce the API based on Mixin Sequencer.

The API based on the latest Mixin Sequencer service is more low-level and decentralized compared to the old version of the API, and the API is also simplified. This API essentially performs all operations by calling the mainnet RPC interface through a proxy, and the main function of this proxy is to facilitate querying users and indexing transaction records.

Registration

Before using the new version of the API, all users, including robots, need to register with the new API. Only after registration can you use the subsequent APIs, and you cannot send transfers and other operations to those unregistered old users.

Before using the latest Mixin Sequencer API, you need to ensure that the user or robot has been updated to the latest TIP protocol PIN code format.

Check if registered

You can check if the user is registered with the new Sequencer API through the following API

Endpoint URL

GET https://api.mixin.one/safe/me
Response
{
"data": {
"user_id": "UUID-USER",
"identity_number": "123456",
"phone": "+8610010",
"full_name": "",
"biography": "",
"avatar_url": "",
"relationship": "",
"mute_until": "0001-01-01T00:00:00Z",
"created_at": "0001-01-01T00:00:00Z",
"code_id": "UUID-CODE",
"code_url": "",
"features": [],
"has_safe": true, // if true, user have register safe.
"session_id": "UUID-SESSION",
"device_status": "",
"has_pin": false,
"receive_message_source": "",
"accept_conversation_source": "",
"accept_search_source": "",
"fiat_currency": "",
"transfer_notification_threshold": 0,
"transfer_confirmation_threshold": 0,
"pin_token_base64": "",
"salt_base64": "",
"tip_key_base64": "",
"tip_counter": 0,
"has_emergency_contact": false
}
}

Register user

Register user No matter if it is a new user or an old user, they are all unregistered users in front of the new version of the API, and they need to use the following API to register.

Endpoint URL

POST https://api.mixin.one/safe/users

Payload

{
"public_key": "ED25519-PUBLIC-KEY-HEX",
"signature": "ED25519-SIGNATURE-OF-USER-UUID-HEX",
"pin_base64": "TIP-PIN-BASE64"
}
Response
{
"data": {
"user_id": "UUID-USER",
"identity_number": "123456",
"phone": "+8610010",
"full_name": "",
"biography": "",
"avatar_url": "",
"relationship": "",
"mute_until": "0001-01-01T00:00:00Z",
"created_at": "0001-01-01T00:00:00Z",
"code_id": "UUID-CODE",
"code_url": "",
"features": [],
"has_safe": true, // if true, user have register safe.
"session_id": "UUID-SESSION",
"device_status": "",
"has_pin": false,
"receive_message_source": "",
"accept_conversation_source": "",
"accept_search_source": "",
"fiat_currency": "",
"transfer_notification_threshold": 0,
"transfer_confirmation_threshold": 0,
"pin_token_base64": "",
"salt_base64": "",
"tip_key_base64": "",
"tip_counter": 0,
"has_emergency_contact": false
}
}

Each user needs to have their own ed25519 private key, which can be the same private key as the current robot or user’s session private key, or generate a new one. We recommend generating a new private key, which facilitates permission separation.

The corresponding PIN signature format is sha256.Sum256([]byte(“SEQUENCER:REGISTER:” + USER-UUID + PUBLIC-KEY-HEX)).

Get a recharge address

The new version of the API can give any user, including a multi-signature group, a recharge address. For now, a user or a multi-signature group can only get one address, and repeated requests will get the same address.

Endpoint URL

POST https://api.mixin.one/safe/deposit/entries

Payload

{
"members": ["UUID-USER-1", "UUID-USER-2"],
"threshold": 1,
"chain_id": "CHAIN-UUID"
}
Response
{
"data": {
"type": "",
"entry_id": "UUID-DEPOSIT-ENTRY",
"threshold": 1,
"members": ["UUID-USER-1", "UUID-USER-2"],
"destination": "ADDRESS",
"tag": "TAG",
"signature": "FOR-VERIFICATION",
"chain_id": "CHAIN-UUID",
"is_primary": true
}
}

Transactions in progress

If you want to get the transactions that are being confirmed in the recharge process, you can get them through the following API, which is for the convenience of some applications to display the recharge progress and other aspects of the work.

Endpoint URL

GET https://api.mixin.one/safe/deposits?asset=UUID&destination=ADDRESS&tag=TAG&offset=RFC3339NANO&limit=500
Response
{
"data": [
{
"deposit_id": "UUID-DEPOSIT",
"destination": "ADDRESS",
"tag": "TAG",
"chain_id": "CHAIN-UUID",
"asset_id": "ASSET-UUID",
"asset_key": "CHAIN-ASSET-KEY",
"amount": "NUMBER",
"transaction_hash": "BLOCKCHAIN-SPECIFIC-HASH",
"output_index": 0,
"block_hash": "BLOCKCHAIN-SPECIFIC-HASH",
"block_number": 333333,
"confirmations": 5,
"threshold": 10,
"state": "pending or confirmed",
"created_at": "RFC3339NANO",
"updated_at": "RFC3339NANO"
}
]
}

Get UTXO list

Because the new version of the API is just a proxy for the mainnet RPC, all operations are based on UTXO. A user, or a multi-signature group, wants to get their own asset situation, needs to access the UTXO list API to get all the UTXO and add them up to get the balance of the relevant asset account.

Endpoint URL

GET https://api.mixin.one/safe/outputs?members=HASH&threshold=NUMBER&offset=NUMBER&limit=NUMBER&state=unspent&order=ASC
Response
{
"data": [
{
"output_id": "OUTPUT-UUID",
"transaction_hash": "KERNEL-HASH",
"output_index": "KERNEL-OUTPUT-INDEX",
"amount": "NUMBER",
"mask": "KERNEL-MASK-KEY",
"keys": "KERNEL-PUBLIC-KEYS",
"senders_hash": "SENDERS-HASH-OPTIONAL",
"senders_threshold": "SENDERS-THRESHOLD-OPTIONAL",
"senders": "SENDERS-UUID-LIST-OPTIONAL",
"receivers_hash": "MEMBERS-HASH",
"receivers_threshold": "MEMBERS-THRESHOLD",
"receivers": "MEMBERS-UUID-LIST",
"extra": "EXTRA-HEX-ENCODING",
"state": "unspent|spent|signed",
"sequence": 12345,
"created_at": "RFC3339NANO",
"updated_at": "RFC3339NANO",
"inscription_hash": "INSCRIPTION-HASH",
"signers": "SIGNERS-UUID-LIST-OPTIONAL",
"request_id": "REQUEST-UUID",
"kernel_asset_id": "KERNEL-ASSET-ID",
"signed_by": "KERNEL-TRASACTION-HASH-OPTIONAL",
"signed_at": "RFC3339NANO-OPTIONAL",
"spent_at": "RFC3339NANO-OPTIONAL"
}
]
}

The offset of this API is not using time, because all UTXO in Mixin Sequencer have a unique numeric sequence number sequence, which can be used directly to sort more conveniently.

The new version of the transaction only has one API, whether it is a normal transfer, a multi-signature transfer, or even a withdrawal, etc., they all need the client to generate a Mixin mainnet compatible transaction and complete the signature, and then send it to the mainnet.

Regardless of whether the transaction initiator is a normal user or a multi-signature group, first get all the UTXO of this user or multi-signature group through the UTXO API, and then get or construct the recipient’s information to get a complete mainnet transaction, and finally send it to the mainnet RPC.

Get payment information

If it is a withdrawal or directly transfer the assets to a Mixin Kernel address, this step is not required. Only when you want to transfer assets to a registered user or multi-signature group of Sequencer, you need to get the one-time payment information of the other party through this API.

Endpoint URL

POST https://api.mixin.one/safe/keys

Payload

[{
"receivers": ["USER-1-UUID", "USER-2-UUID"],
"index": 3,
"hint": "UNIQUE-UUID"
}]
Response
{
"data": [
{
"mask": "KERNEL-MASK-KEY",
"keys": ["KERNEL-PUBLIC-KEYS", "KERNEL-PUBLIC-KEYS"]
}
]
}

Verify transaction format

Regardless of whether the recipient is a Sequencer user, after the transaction is constructed, you need to send the transaction to Sequencer to verify that the transaction format is correct, and Sequencer will return the corresponding view key signature.

Endpoint URL

POST https://api.mixin.one/safe/transaction/requests

Payload

[{
"request_id": "UNIQUE-UUID",
"raw": "KERNEL-RAW-TRANSACTION"
}]
Response
{
"data": [
{
"request_id": "UUID-REQUEST",
"transaction_hash": "KERNEL-HASH",
"asset_id": "UUID-ASSET",
"kernel_asset_id": "KERNEL-ASSET-HASH",
"amount": "NUMBER",
"senders_hash": "SENDERS-HASH",
"senders_threshold": 1,
"senders": ["UUID-USER-1", "UUID-USER-2"],
"signers": ["UUID-USER-1", "UUID-USER-2"],
"extra": "",
"state": "signed or spent",
"raw_transaction": "",
"created_at": "RFC3339NANO",
"updated_at": "RFC3339NANO",

"inscription_hash": "INSCRIPTION-HASH",
"receivers": [
{
"members": ["UUID-USER-1", "UUID-USER-2"],
"members_hash": "MEMBERS-HASH",
"threshold": 1
},
],
"views":[
{
"destination": "ADDRESS",
"tag": "TAG",
"withdrawal_hash": "WITHDRAWAL-HASH"
}
]
},
]
}

The successfully returned views array is exactly the view key part signature corresponding to each input in order. Note that both the input and output of this API are arrays, which is for the convenience of batch verification of transactions.

Sign and send transaction

After receiving the view key signature from Sequencer, the client can use their own ed25519 private key to perform the second formal signature, and the specific code of the signature can be operated using the relevant SDK. At this time, the entire transaction is considered to be completely constructed, and then it can be sent out through the following API.

Endpoint URL

POST https://api.mixin.one/safe/transaction

Payload

[{
"request_id": "UNIQUE-UUID",
"raw": "KERNEL-RAW-TRANSACTION"
}]
Response
{
"data": [
{
"request_id": "UUID-REQUEST",
"transaction_hash": "KERNEL-HASH",
"asset_id": "UUID-ASSET",
"kernel_asset_id": "KERNEL-ASSET-HASH",
"amount": "NUMBER",
"senders_hash": "SENDERS-HASH",
"senders_threshold": 1,
"senders": ["UUID-USER-1", "UUID-USER-2"],
"signers": ["UUID-USER-1", "UUID-USER-2"],
"extra": "",
"state": "signed or spent",
"raw_transaction": "",
"created_at": "RFC3339NANO",
"updated_at": "RFC3339NANO",

"inscription_hash": "INSCRIPTION-HASH",
"receivers": [
{
"members": ["UUID-USER-1", "UUID-USER-2"],
"members_hash": "MEMBERS-HASH",
"threshold": 1
},
],
"views":[
{
"destination": "ADDRESS",
"tag": "TAG",
"withdrawal_hash": "WITHDRAWAL-HASH"
}
]
},
]
}

Note that this transaction can be sent directly through the Mixin Kernel mainnet RPC, but we do not recommend this operation, because if it is sent directly, Sequencer cannot correctly index this transaction and cannot provide transaction and snapshot query services.

Query transaction

After the transaction is correctly sent out through the Sequencer API, you can query the transaction status through the request UUID.

Endpoint URL

GET https://api.mixin.one/safe/transactions/:id
Response
{
"data": {
"request_id": "UUID-REQUEST",
"transaction_hash": "KERNEL-HASH",
"asset": "KERNEL-ASSET-HASH",
"amount": "NUMBER",
"senders_hash": "SENDERS-HASH",
"senders_threshold": 1,
"senders": ["UUID-USER-1", "UUID-USER-2"],
"signers": ["UUID-USER-1", "UUID-USER-2"],
"extra": "",
"state": "signed or spent",
"raw_transaction": "",
"created_at": "RFC3339NANO",
"updated_at": "RFC3339NANO",
"snapshot_hash": "SNAPSHOT-HASH",
"snapshot_at": "RFC3339NANO",
"receivers": [
{
"members": ["UUID-USER-1", "UUID-USER-2"],
"members_hash": "MEMBERS-HASH",
"threshold": 1
},
],
"views":[
{
"destination": "ADDRESS",
"tag": "TAG",
"withdrawal_hash": "WITHDRAWAL-HASH"
}
]
}
}

Snapshot

The new version of the API provides a relatively compatible snapshots API for ease of use, which is similar to the old version of the API.

If the authentication information of the request for this API is a robot, you can add the app parameter to return the snapshots of all sub-users created by this robot.

Endpoint URL

GET https://api.mixin.one/safe/snapshots?app=UUID&asset=UUID&opponent=UUID&offset=RFC3339NANO&limit=500

The parameter app, asset, opponent can't use in the same time

Response
{
"data": [
{
"snapshot_id": "SNAPSHOT-UUID",
"user_id": "USER-UUID",
"opponent_id": "OPPONENT-UUID-OPTIONAL",
"transaction_hash": "KERNEL-HASH",
"asset_id": "ASSET-UUID",
"kernel_asset_id": "ASSET-HASH",
"amount": "NUMBER",
"memo": "EXTRA-HEX-ENCODING",
"request_id": "REQUEST-UUID",
"created_at": "RFC3339NANO",

"inscription_hash": "INSCRIPTION-HASH",
"deposit": {
"deposit_hash": "DEPOSIT-HASH",
"deposit_index": 1,
"sender": "SOME-STRING",
"destination": "DEPOSIT-DESTINATION",
"tag": "DEPOSIT-TAG",
},
"withdrawal": {
"withdrawal_hash": "WITHDRAWAL-HASH",
"receiver": "SOME-STRING",
},
}
]
}

multisigs

The new version of multi-signature is the same as the old version. The client still needs to construct a raw transaction. Other operations are similar to those of the old version.

create multisigs

Endpoint URL

POST https://api.mixin.one/safe/multisigs

Payload

[{
"request_id": "UNIQUE-UUID",
"raw": "KERNEL-RAW-TRANSACTION"
}]
Response
{
"data": [
{
"request_id": "UUID-REQUEST",
"transaction_hash": "KERNEL-HASH",
"asset_id": "UUID-ASSET",
"kernel_asset_id": "KERNEL-ASSET-HASH",
"amount": "NUMBER",
"senders_hash": "SENDERS-HASH",
"senders_threshold": 1,
"senders": ["UUID-USER-1", "UUID-USER-2"],
"signers": ["UUID-USER-1", "UUID-USER-2"],
"extra": "",
"raw_transaction": "",
"created_at": "RFC3339NANO",
"updated_at": "RFC3339NANO",
"receivers": [
{
"members": ["UUID-USER-1", "UUID-USER-2"],
"members_hash": "MEMBERS-HASH",
"threshold": 1
},
],
"views":[
{
"destination": "ADDRESS",
"tag": "TAG",
"withdrawal_hash": "WITHDRAWAL-HASH"
}
]
},
...
]
}

sign multisigs

Endpoint URL

POST https://api.mixin.one/safe/multisigs/:id/sign

Payload

{
"request_id": "UNIQUE-UUID",
"raw": "KERNEL-RAW-TRANSACTION"
}
Response
{
"data": {
"request_id": "UUID-REQUEST",
"transaction_hash": "KERNEL-HASH",
"asset_id": "UUID-ASSET",
"kernel_asset_id": "KERNEL-ASSET-HASH",
"amount": "NUMBER",
"senders_hash": "SENDERS-HASH",
"senders_threshold": 1,
"senders": ["UUID-USER-1", "UUID-USER-2"],
"signers": ["UUID-USER-1", "UUID-USER-2"],
"extra": "",
"raw_transaction": "",
"created_at": "RFC3339NANO",
"updated_at": "RFC3339NANO",
"receivers": [
{
"members": ["UUID-USER-1", "UUID-USER-2"],
"members_hash": "MEMBERS-HASH",
"threshold": 1
},
],
"views":[
{
"destination": "ADDRESS",
"tag": "TAG",
"withdrawal_hash": "WITHDRAWAL-HASH"
}
]
}
}

unlock multisigs

notice, multisigs can only be canceled if the signature is not completed

Endpoint URL

POST https://api.mixin.one/safe/multisigs/:id/unlock

Payload

{
"request_id": "UNIQUE-UUID",
"raw": "KERNEL-RAW-TRANSACTION"
}
Response
{
"data": {
"request_id": "UUID-REQUEST",
"transaction_hash": "KERNEL-HASH",
"asset_id": "UUID-ASSET",
"kernel_asset_id": "KERNEL-ASSET-HASH",
"amount": "NUMBER",
"senders_hash": "SENDERS-HASH",
"senders_threshold": 1,
"senders": ["UUID-USER-1", "UUID-USER-2"],
"signers": ["UUID-USER-1", "UUID-USER-2"],
"extra": "",
"raw_transaction": "",
"created_at": "RFC3339NANO",
"updated_at": "RFC3339NANO",
"receivers": [
{
"members": ["UUID-USER-1", "UUID-USER-2"],
"members_hash": "MEMBERS-HASH",
"threshold": 1
},
],
"views":[
{
"destination": "ADDRESS",
"tag": "TAG",
"withdrawal_hash": "WITHDRAWAL-HASH"
}
]
}
}

fetch multisigs

Endpoint URL

GET https://api.mixin.one/safe/multisigs/:id

Payload

{
"request_id": "UNIQUE-UUID",
"raw": "KERNEL-RAW-TRANSACTION"
}
Response
{
"data": {
"request_id": "UUID-REQUEST",
"transaction_hash": "KERNEL-HASH",
"asset_id": "UUID-ASSET",
"kernel_asset_id": "KERNEL-ASSET-HASH",
"amount": "NUMBER",
"senders_hash": "SENDERS-HASH",
"senders_threshold": 1,
"senders": ["UUID-USER-1", "UUID-USER-2"],
"signers": ["UUID-USER-1", "UUID-USER-2"],
"extra": "",
"raw_transaction": "",
"created_at": "RFC3339NANO",
"updated_at": "RFC3339NANO",
"receivers": [
{
"members": ["UUID-USER-1", "UUID-USER-2"],
"members_hash": "MEMBERS-HASH",
"threshold": 1
},
],
"views":[
{
"destination": "ADDRESS",
"tag": "TAG",
"withdrawal_hash": "WITHDRAWAL-HASH"
}
]
}
}

How to fetch user's assets balance

App can get user's assets balance in the Mixin Messenger enviroment.

window.assetsCallbackFunction = (assets: string) => {
const as: Asset[] = JSON.parse(assets)
if (as) {
as.forEach((x) => {
if (x.asset_id === getEnvConfig().assetIdFund) {
setBalance(x.balance)
}
})
}
}

if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.MixinContext && window.webkit.messageHandlers.getAssets) {
window.webkit.messageHandlers.getAssets.postMessage([[], 'assetsCallbackFunction'])
} else if (window.MixinContext && typeof window.MixinContext.getAssets === 'function') {
window.MixinContext.getAssets([], 'assetsCallbackFunction')
}

Precautions

The new version of the API has no changes in the data format of the request and return, including the authentication of JWT and OAuth. In addition, most of the old APIs, as long as they are unrelated to assets, are still normally available, such as contacts, messages, groups, etc.

MEMO format

All memo or extra fields in the new version of the API are now uniformly HEX encoded raw data, that is, whatever the user or robot enters is what it is, and there is no longer any special encoding requirements such as msgpack or base64.

New error code

One thing to note is a new error code 10404, which means that this user has not registered to the latest API, and it is recommended to send a reminder to the user to let them upgrade as soon as possible to use it.

Batch transfer

Because the new API is completely based on the Mixin Kernel mainnet transaction format, you can freely combine and use UTXO, such as if you want to transfer to 100 people at the same time, you can request the payment information of 100 people at once and then construct a transaction to complete it.