Single Payment Signature Structure
To authorize payment operations the user must generate a cryptographic signature compliant with the EIP-191 standard.
The signature is created by signing a precisely formatted string message derived from the payment details. The structure uses conditional logic to determine whether to use a direct address or identity string for the recipient.
Signed Message Format
The message is constructed by concatenating the following components as strings, separated by commas (,
):
string.concat(
_priorityFlag ? "f4e1895b" : "4faa1fa2",
",",
_receiverAddress == address(0)
? _receiverIdentity
: AdvancedStrings.addressToString(_receiverAddress),
",",
AdvancedStrings.addressToString(_token),
",",
Strings.toString(_amount),
",",
Strings.toString(_priorityFee),
",",
Strings.toString(_nonce),
",",
_priorityFlag ? "true" : "false",
",",
AdvancedStrings.addressToString(_executor)
);
Message Components
1. Function Selector (Hex String):
f4e1895b
: Used when_priorityFlag
istrue
(asynchronous processing)4faa1fa2
: Used when_priorityFlag
isfalse
(synchronous processing)
2. Recipient Identifier (String):
- If
_receiverAddress == address(0)
: Use_receiverIdentity
string directly - If
_receiverAddress != address(0)
: UseAdvancedStrings.addressToString(_receiverAddress)
- Purpose: Specifies the intended recipient using either address or identity
3. Token Address (String):
- The result of
AdvancedStrings.addressToString(_token)
- Purpose: Identifies the token being transferred
4. Amount (String):
- The result of
Strings.toString(_amount)
- Purpose: Specifies the quantity of the token to be transferred
5. Priority Fee (String):
- The result of
Strings.toString(_priorityFee)
- Purpose: Specifies the fee paid to staking holders
6. Nonce (String):
- The result of
Strings.toString(_nonce)
- Purpose: Provides replay protection for the transaction
7. Priority Flag (String):
"true"
: If_priorityFlag
istrue
(asynchronous)"false"
: If_priorityFlag
isfalse
(synchronous)- Purpose: Explicitly includes the execution mode in the signed message
8. Executor Address (String):
- The result of
AdvancedStrings.addressToString(_executor)
- Purpose: Specifies the address authorized to submit this payment request
Example
Here's a practical example of constructing a signature message for sending 0.05 ETH:
Scenario: User wants to send 0.05 ETH to another user using synchronous processing
Parameters:
_priorityFlag
:false
(synchronous processing)_receiverAddress
:0x742c7b6b472c8f4bd58e6f9f6c82e8e6e7c82d8c
_token
:address(0)
(ETH)_amount
:50000000000000000
(0.05 ETH in wei)_priorityFee
:1000000000000000
(0.001 ETH in wei)_nonce
:42
_executor
:0x0000000000000000000000000000000000000000
(unrestricted)
Resulting message string:
4faa1fa2,0x742c7b6b472c8f4bd58e6f9f6c82e8e6e7c82d8c,0x0000000000000000000000000000000000000000,50000000000000000,1000000000000000,42,false,0x0000000000000000000000000000000000000000
Message breakdown:
4faa1fa2
- Function selector for synchronous processing0x742c7b6b472c8f4bd58e6f9f6c82e8e6e7c82d8c
- Receiver address0x0000000000000000000000000000000000000000
- Token address (ETH)50000000000000000
- Amount in wei (0.05 ETH)1000000000000000
- Priority fee in wei (0.001 ETH)42
- Noncefalse
- Priority flag (synchronous)0x0000000000000000000000000000000000000000
- Executor (unrestricted)
Example with Username
Here's another example using a username instead of an address:
Scenario: User wants to send 0.05 ETH to username "example" using asynchronous processing
Parameters:
_priorityFlag
:true
(asynchronous processing)_receiverAddress
:address(0)
(using identity instead)_receiverIdentity
:"example"
_token
:address(0)
(ETH)_amount
:50000000000000000
(0.05 ETH in wei)_priorityFee
:2000000000000000
(0.002 ETH in wei)_nonce
:15
_executor
:0x0000000000000000000000000000000000000000
(unrestricted)
Resulting message string:
f4e1895b,example,0x0000000000000000000000000000000000000000,50000000000000000,2000000000000000,15,true,0x0000000000000000000000000000000000000000
Message breakdown:
f4e1895b
- Function selector for asynchronous processingexample
- Receiver identity (username)0x0000000000000000000000000000000000000000
- Token address (ETH)50000000000000000
- Amount in wei (0.05 ETH)2000000000000000
- Priority fee in wei (0.002 ETH)15
- Noncetrue
- Priority flag (asynchronous)0x0000000000000000000000000000000000000000
- Executor (unrestricted)
AdvancedStrings.addressToString
converts an address to a lowercase hexadecimal string with "0x" prefix (e.g., "0x1234...abcd")Strings.toString
converts a number to a string_priorityFlag
indicates whether the payment will be executed asynchronously (true
) or synchronously (false
)- The function selector (
4faa1fa2
for synchronous orf4e1895b
for asynchronous) is determined by the_priorityFlag
value - Recipient determination: If
_receiverAddress == address(0)
, the_receiverIdentity
string is used directly; otherwise, the address is converted to string