Signet Chain Signatures Program
Solana program for cross-chain signature requests with verified response callbacks.
Overview
This program enables users to request ECDSA signatures from the Signet MPC network, supporting both simple signing and bidirectional cross-chain transactions.
Instructions Reference
Developer Instructions
These are the primary instructions for building applications:
| Instruction | Description |
|---|---|
sign |
Request signature on a 32-byte payload |
sign_bidirectional |
Cross-chain tx with execution result callback |
get_signature_deposit |
Query the current deposit amount (view function) |
Sign Bidirectional Flow
The bidirectional flow enables cross-chain transaction execution with verified response callbacks:
User Solana (Source) MPC Network Destination Chain
│ │ │ │
│ sign_bidirectional() │ │ │
├───────────────────────►│ │ │
│ │ SignBidirectionalEvent │ │
│ ├────────────────────────►│ │
│ │◄──── respond() ─────────┤ │
│ │ │ │
│ Poll SignatureRespondedEvent │ │
│◄───────────────────────┤ │ │
│ │ │ │
│ Broadcast signed tx ───┼─────────────────────────┼───────────────────►│
│ │ │◄── Light client ───┤
│ │◄─ respond_bidirectional() │
│ │ │ │
│ Poll RespondBidirectionalEvent │ │
│◄───────────────────────┤ │ │
Phase 1: Sign Request
- User calls
sign_bidirectionalwith serialized unsigned transaction - Program emits
SignBidirectionalEvent - MPC parses event and generates unique request ID
Phase 2: Signature Delivery
- MPC signs the transaction hash
- Stores transaction in backlog for observation
- Calls
respond, emittingSignatureRespondedEvent - User polls for
SignatureRespondedEventto get signature
Phase 3: User Broadcast
- User assembles signed transaction (serialized data + signature)
- User broadcasts to destination chain
- The MPC does NOT broadcast - this is the user's responsibility
Phase 4: Light Client Observation
- MPC light client monitors destination chain blocks
- Detects transaction confirmation by hash
- Extracts execution status (success/failure)
Phase 5: Output Extraction
- For contract calls: MPC extracts return value
- For simple transfers: empty success indicator
- Output deserialized using
output_deserialization_schema
Phase 6: Respond Bidirectional
- MPC serializes output using
respond_serialization_schema - Signs
keccak256(request_id || serialized_output) - Calls
respond_bidirectional - Program emits
RespondBidirectionalEventfor user to poll
Request ID Generation
Each request has a unique ID for tracking:
// For sign_bidirectional (packed encoding):
request_id = keccak256(
sender || serialized_tx || caip2_id || key_version ||
path || algo || dest || params
)
Serialization Schemas
Cross-chain data encoding uses two schemas:
| Schema | Direction | Purpose |
|---|---|---|
output_deserialization_schema |
Destination → MPC | Parse execution result from destination chain |
respond_serialization_schema |
MPC → Source | Serialize response for source chain consumption |
See destination chain guides (e.g., EVM) for format details and examples.
Error Handling
Failed destination chain transactions are indicated with magic prefix:
const MAGIC_ERROR_PREFIX: = ;
// Check if response indicates failure:
Address Derivation
Each user gets a unique destination chain address derived from:
epsilon = derive_epsilon(sender_pubkey, derivation_path)
user_pubkey = derive_key(mpc_root_pubkey, epsilon)
// Address format is chain-specific (see destination chain guides)
Response Signature Verification
The respond_bidirectional response is signed using a special derivation path:
const RESPONSE_DERIVATION_PATH: &str = "solana response key";
// Response epsilon derivation:
epsilon = derive_epsilon(key_version, sender_pubkey, "solana response key")
response_pubkey = derive_key(mpc_root_pubkey, epsilon)
The signature is computed over:
message_hash = keccak256(request_id || serialized_output)
To verify the response signature, clients must:
- Recover the public key from the signature using
secp256k1_recover - Derive the expected response public key using the
"solana response key"path - Compare the recovered public key with the expected response public key
Security Considerations
Security Properties
-
Request ID Uniqueness: Each request has a unique ID computed from
keccak256(sender || tx || chain_id || ...)preventing replay attacks -
Response Authenticity: Responses are signed over
keccak256(request_id || serialized_output)using MPC threshold signatures -
Output Verification: The
output_deserialization_schemaandrespond_serialization_schemaensure consistent data encoding across chains -
Key Isolation: Each user has isolated keys through unique derivation paths (
epsilon = derive_epsilon(predecessor, path)) -
Light Client Security: The MPC light client validates destination chain consensus without trusting an RPC provider
Destination Chain Guides
For detailed integration guides with real code examples, see:
- EVM - Solana → EVM (Ethereum, Arbitrum, Optimism, Base, Polygon)
License
MIT