Mixin Sequencer API
最新的 Mixin 整体网络是以 Mixin Safe 为基础的,网络主要是 Mixin Kernel 和 Mixin Safe 两部分。为了方便使用,我们开发了 Mixin Sequencer 来索引排序 Kernel 的所有相关交易,所以产品上我们会说基于 Mixin Safe 的新网络,但是这里主要介绍基于 Mixin Sequencer 的 API。
基于最新的 Mixin Sequencer 服务的 API 与旧版本的 API 相比主要是更底层更去中心化,同时 API 也更简化了。这个 API 本质上所有操作都是在通过一个代理调用主网的 RPC 接口,这个代理的主要作用是方便查询用户与索引交易记录。
注册
使用新版本的 API 之前,所有用户,包括机器人,都需要在新 API 注册。只有注册之后才能使用后续的 API,而且无法给那些未注册的老用户发送转账等操作。
在使用最新的 Mixin Sequencer API 之前,需要确保用户或者机器人已经更新到了最新的 TIP 协议的 PIN 码格式。
检查是否注册
通过下面的 API 可以检查用户是不是注册了新的 Sequencer API
API 端点 URL
GET https://api.mixin.one/safe/me
{
"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
}
}
注册用户
不管是新用户,还是老用户,在新版本 API 面前都是一样的未注册用户,注册需要使用下面的 API
API 端点 URL
POST https://api.mixin.one/safe/users
请求体
{
"public_key": "ED25519-PUBLIC-KEY-HEX",
"signature": "ED25519-SIGNATURE-OF-USER-UUID-HEX",
"pin_base64": "TIP-PIN-BASE64"
}
{
"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
}
}
每个用户都需要有一个自己的 ed25519 私钥,这个私钥可以是当前机器人或者用户的 session private key 相同的私钥,也可以生成一个新的。我们推荐生成一个新的私钥,这样方便权限分离。
相应的 PIN 的签名格式是 sha256.Sum256([]byte("SEQUENCER:REGISTER:" + USER-UUID + PUBLIC-KEY-HEX))。
获取充值地址
新版本的 API 可以给任意用户包括一个多签组获取充值地址,暂时一个用户或者一个多签组只能获取一个地址,重复获取得到的都是同一个地址。
API 端点 URL
POST https://api.mixin.one/safe/deposit/entries
请求体
{
"members": ["UUID-USER-1", "UUID-USER-2"],
"threshold": 1,
"chain_id": "CHAIN-UUID"
}
{
"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
}
}
充值中的交易
如果要获取正在充值确认中的交易可以通过下面的 API 获取,这个 API 是为了方便一些应用展示充值进度等方面的工作。
API 端点 URL
GET https://api.mixin.one/safe/deposits?asset=UUID&destination=ADDRESS&tag=TAG&offset=RFC3339NANO&limit=500
{
"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"
}
]
}
获取 UTXO 列表
因为新版本 API 只是主网 RPC 的代理,所有操作都是基于 UTXO 的。一个用户,或者一个多签组,想要得到自己的资产情况,需要访问 UTXO 列表 API 得到所有的 UTXO 并且累加就是相关资产账户的余额。
API 端点 URL
GET https://api.mixin.one/safe/outputs?members=HASH&threshold=NUMBER&offset=NUMBER&limit=NUMBER&state=unspent&order=ASC
API 端点 URL
GET https://api.mixin.one/safe/outputs?app=UUID&offset=NUMBER&limit=NUMBER
{
"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"
}
]
}
这个 API 的 offset 不是使用的时间,是因为所有 UTXO 在 Mixin Sequencer 里都有一个唯一的数字序号 sequence,可以直接使用这个序号来排序更方便。
交易相关
新版本的交易只有一个 API,不管是普通的转账还是多签转账,甚至是提现等,统一都需要客户端自己生成 Mixin 主网兼容的交易并完成签名后,发送到主网。
不管交易发起方是一个普通用户还是多签组,首先通过 UTXO API 得到这个用户或者多签组的所有 UTXO,然后通过获取或者构造收款人的信息来得到一个完整的主网交易,最后发送到主网 RPC。
获取收款信息
如果是提现或者直接将资产转给一个 Mixin Kernel 地址,是不需要这一步的。只有想要将资产转给 Sequencer 的注册用户或者多签组时,需要通过这个 API 得到对方的一次性收款信息。
API 端点 URL
POST https://api.mixin.one/safe/keys
请求体
[{
"receivers": ["USER-1-UUID", "USER-2-UUID"],
"index": 3,
"hint": "UNIQUE-UUID"
}]
{
"data": [
{
"mask": "KERNEL-MASK-KEY",
"keys": ["KERNEL-PUBLIC-KEYS", "KERNEL-PUBLIC-KEYS"]
}
]
}
验证交易格式
不论收款人是不是 Sequencer 用户,在交易构造完成后,都需要将交易发送给 Sequencer 验证交易格式没有问题,那 Sequencer 会返回相应的 view key 签名。
API 端点 URL
POST https://api.mixin.one/safe/transaction/requests
请求体
[{
"request_id": "UNIQUE-UUID",
"raw": "KERNEL-RAW-TRANSACTION"
}]
{
"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"
}
]
},
]
}
成功返回的 views 数组就是完全按顺序对应的每个 input 的 view key 部分签名。需要注意的是这个 API 传入和返回的都是数组,这是为了方便批量验证交易。
签名发送交易
收到 Sequencer 的 view key 签名后,客户端可以使用自己的 ed25519 private key 进行第二步正式签名,签名的具体代码可以使用相关的 SDK 来操作。这时候整个交易才算完全构造完成,然后就可以通过下面的 API 发送出去。
API 端点 URL
POST https://api.mixin.one/safe/transaction
请求体
[{
"request_id": "UNIQUE-UUID",
"raw": "KERNEL-RAW-TRANSACTION"
}]
{
"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"
}
]
},
]
}
需要注意的是,这笔交易完全可以通过 Mixin Kernel 主网 RPC 直接发送,但是我们不推荐这样操作,因为如果直接发送后 Sequencer 无法正确索引这笔交易,就无法提供交易和 snapshot 查询服务。
查询交易
如果交易正确的通过 Sequencer API 发送出去之后,就可以通过 request UUID 来查询交易的状态。
API 端点 URL
GET https://api.mixin.one/safe/transactions/:id
{
"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 相关
新版本的 API 为了方便使用,提供一个相对兼容旧版本习惯的 snapshots API,这个 API 与旧版本 API 类似。
如果请求这个 API 的认证信息是一个机器人,可以通过添加 app 参数来返回这个机器人创建的所有子用户的 snapshots。
API 端点 URL
GET https://api.mixin.one/safe/snapshots?app=UUID&asset=UUID&opponent=UUID&offset=RFC3339NANO&limit=500
其中 app, asset, opponent 不可以同时存在
{
"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",
},
}
]
}
多签相关
新版本的多签与旧版本相同,还是需要客户端来构造 raw transaction, 其它的操作跟旧版本的操作类似。
创建多签
API 端点 URL
POST https://api.mixin.one/safe/multisigs
请求体
[{
"request_id": "UNIQUE-UUID",
"raw": "KERNEL-RAW-TRANSACTION"
}]
{
"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"
}
]
},
...
]
}
多签签名
API 端点 URL
POST https://api.mixin.one/safe/multisigs/:id/sign
请求体
{
"request_id": "UNIQUE-UUID",
"raw": "KERNEL-RAW-TRANSACTION"
}
{
"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"
}
]
}
}
取消签名
注意,只有在签名未完成的情况下可以取消签名
API 端点 URL
POST https://api.mixin.one/safe/multisigs/:id/unlock
请求体
{
"request_id": "UNIQUE-UUID",
"raw": "KERNEL-RAW-TRANSACTION"
}
{
"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"
}
]
}
}
获取签名信息
API 端点 URL
GET https://api.mixin.one/safe/multisigs/:id
请求体
{
"request_id": "UNIQUE-UUID",
"raw": "KERNEL-RAW-TRANSACTION"
}
{
"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"
}
]
}
}
如何获取用户资产余额
在 Mixin Messenger 环境中,可以在机器人会话的网页中,通过 js 来获取用户的余额
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')
}
注意事项
新版本 API 与旧版本 API 在请求与返回的数据格式上没有变化,包括认证的 JWT 与 OAuth 方式都没有变化。另外大部分旧的 API,只要与资产无关的,都依然是正常可用的,比如联系人、消息、群组等。
MEMO 格式
新版本 API 里的所有 memo 或者 extra 字段现在都是统一的 HEX 编码的原始数据,也就是用户或者机器人传入的是啥就是啥,不再有 msgpack 或者 base64 等特殊的编码要求。
新的错误码
需要注意的就是一个新的错误码 10404,代表这个用户还没注册到最新的 API,这时推荐给用户发送提醒让他们尽快升级才能使用。
批量转账
因为新的 API 完全基于 Mixin Kernel 的主网交易格式,所以可以自由的组合使用 UTXO,比如想要同时对 100 个人转账,可以一次请求 100 个人的收款信息然后构造一个 transactin 即可完成。