Message encoding
When a user submits an order, the application prepares a message whose payload is the transaction request. Either the application or the wallet needs to sign the transaction request, in one of the following ways:
-
The wallet signs the transaction
The application and wallet communicate with each other through messages containing the transaction using broadcast signing or raw signing:Broadcast signing The wallet receives the transaction payload from the application. This method is fully transparent to the user, as the wallet can present the transaction’s parameters to the user. When the user approves, the wallet constructs the hash and computes the signature. Multi-Party Computation (MPC) wallets can use StarkEx transaction-specific parameters in the policy engine in order to limit some operations, such as adding another signer when the amount exceeds a given threshold.
Raw signing The application hashes the transaction. The wallet receives the hash of the transaction and signs it.
-
The application signs the transaction
The application hashes and signs the transaction request.
Broadcast signing flow
The following sequence of events takes place, concluding with the StarkEx gateway receiving a signed, encoded message with the transaction request:
-
A user submits a transaction request using the application.
-
The application sends the transaction request to a wallet.
-
The wallet runs a Pedersen hash function on the parameters in the transaction request.
-
The wallet prompts the user to sign the request.
-
The wallet signs the transaction and sends the resulting signature back to the application.
-
The application sends an encoded message to the StarkEx gateway that includes the transaction request and the signature hash.
Raw signing flow
-
A user submits a transaction request using the application.
-
The application runs a Pedersen hash function on the parameters in the transaction request.
-
The application sends the hash to a wallet.
-
The wallet prompts the user to sign the request.
-
The wallet signs the hash and sends the resulting signature back to the application.
-
The application sends an encoded message to the StarkEx gateway that includes the transaction request and the signature hash.
Application signing flow
-
A user submits a transaction request using the application.
-
The application runs a Pedersen hash function on the parameters in the transaction request.
-
The application signs the hash.
-
The application sends an encoded message to the StarkEx gateway that includes the transaction request and the signature hash.
Supported order types
The following order types are currently supported:
WithdrawalToAddress
|
(StarkEx Perpetual v2.0) Withdrawal to a specific L1 address. Requests collateral to move from the L2 state to L1. |
Withdrawal
|
(StarkEx Perpetual v1.0) Requests collateral to move from the L2 state to L1. |
Limit order with fees |
Declares intent to sell a certain amount of a certain asset in exchange for a different asset at a certain ratio. One of the assets must be the collateral.
|
Transfer
|
Transfer, requests collateral to be transferred from one vault to another. |
ConditionalTransfer
|
Conditional transfer, requests collateral to be transferred from one vault to another if some onchain event is recorded. |
For information on using the corresponding APIs for these transaction types, see Transactions in the StarkEx Perpetual REST API reference.
Withdrawal to address` (StarkEx Perpetual v2.0)
Message payload
{
"type": 7 (10 bits),
"asset_id_collateral": uint251,
"eth_address": uint251,
"position_id": uint64,
"amount": uint64,
"nonce": uint32,
"expiration_timestamp": uint32, // hours_since_Unix_epoch / 3600
}
Message hash chain format
Pedersen_hash( asset_id_collateral, eth_address, packed_message )
type | position_id | nonce | amount | expiration_timestamp | 0 padding |
---|---|---|---|---|---|
10 bits |
64 bits |
32 bits |
64 bits |
32 bits |
49 bits |
Corresponding flow
Corresponding transaction in StarkEx API
Limit order with fees
Message payload
{
"type": 3 // (10 bits),
"is_buying_synthetic": uint64, // The number of bits is not a signed parameter.
"asset_id_synthetic": uint251,
"asset_id_collateral": uint251,
"asset_id_fee": uint251,
"amount_synthetic": uint64,
"amount_collateral": uint64,
"max_amount_fee": uint64,
"position_id": uint64,
"nonce": uint32,
"expiration_timestamp": uint32 // hours_since_Unix_epoch / 3600
}
The number of bits for |
Set parameters as follows:
-
If
is_buying_synthetic == 1
:asset_id_sell = asset_id_collateral
asset_id_buy = asset_id_synthetic
amount_sell = amount_collateral
amount_buy = amount_synthetic
-
If
is_buying_synthetic == 0
:asset_id_sell = asset_id_synthetic
asset_id_buy = asset_id_collateral
amount_sell = amount_synthetic
amount_buy = amount_collateral
Message hash chain format
Pedersen_hash( asset_id_sell, asset_id_buy, asset_id_fee, packed_message0, packed_message1 )
amount_sell | amount_buy | max_amount_fee | nonce |
---|---|---|---|
64 bits |
64 bits |
64 bits |
32 bits |
type | position_id | position_id | position_id | expiration_timestamp | 0 padding |
---|---|---|---|---|---|
10 bits |
64 bits |
64 bits |
64 bits |
32 bits |
17 bits |
|
Corresponding flows
Transfer
Message payload
{
"type": 4 (10 bits),
"asset_id": uint251,
"asset_id_fee": uint251,
"receiver_public_key": uint251,
"sender_position_id": uint64,
"receiver_position_id": uint64,
"src_fee_position_id": uint64,
"amount": uint64,
"max_amount_fee": uint64,
"nonce": uint32,
"expiration_timestamp": uint32, // hours_since_Unix_epoch / 3600
}
Message hash chain format
Pedersen_hash( asset_id, asset_id_fee, receiver_public_key, packed_message0, packed_message1 )
sender_position_id | receiver_position_id | src_fee_position_id | nonce |
---|---|---|---|
64 bits |
64 bits |
64 bits |
32 bits |
type | amount | max_amount_fee | expiration_timestamp | 0 padding |
---|---|---|---|---|
10 bits |
64 bits |
64 bits |
32 bits |
81 bits |
Corresponding flows
ConditionalTransfer
Message payload
{
"type": 5 (10 bits),
"asset_id": uint251,
"asset_id_fee": uint251,
"receiver_public_key": uint251,
"condition": uint251,
"sender_position_id": uint64,
"receiver_position_id": uint64,
"src_fee_position_id": uint64,
"amount": uint64,
"max_amount_fee": uint64,
"nonce": uint32,
"expiration_timestamp": uint32, // hours_since_Unix_epoch / 3600
}
Message hash chain format
Pedersen_hash( asset_id, asset_id_fee, receiver_public_key, condition, packed_message0, packed_message1 )
sender_position_id | receiver_position_id | src_fee_position_id | nonce |
---|---|---|---|
64 bits |
64 bits |
64 bits |
32 bits |
type | amount | max_amount_fee | expiration_timestamp | 0 padding |
---|---|---|---|---|
10 bits |
64 bits |
64 bits |
32 bits |
81 bits |
Corresponding flows
Withdrawal
(StarkEx Perpetual v1.0 only)
Signature construction
Where:
ECDSA is the regular elliptic curve digital signature algorithm, \(H\) is the Pedersen hash function, and \(w_{1-n}\) are 252-bit words.
Parameters
\(k_{private}\) |
The user’s private Stark key |
||||||||||||
\(w_1\) |
The withdrawn |
||||||||||||
\(w_5\) |
Defined as follows: +----+----------------+---------+---------+---------+------------+ #bits | 10 | 64 | 32 | 32 | 32 | 49 | +----+----------------+---------+---------+---------+------------+ label A B C D E F Where:
|