Expand description
§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: [u8; 4] = [0xde, 0xad, 0xbe, 0xef];
// Check if response indicates failure:
fn is_error(output: &[u8]) -> bool {
output.starts_with(&[0xde, 0xad, 0xbe, 0xef])
}§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
Modules§
- accounts
- An Anchor generated module, providing a set of structs
mirroring the structs deriving
Accounts, where each field is aPubkey. This is useful for specifying accounts for a client. - chain_
signatures - evm
- Solana → EVM Destination Chain Integration Guide
- instruction
- An Anchor generated module containing the program’s set of
instructions, where each method handler in the
#[program]mod is associated with a struct defining the input arguments to the method. These should be used directly, when one wants to serialize Anchor instruction data, for example, when speciying instructions on a client. - program
- Module representing the program.
Structs§
- Admin
Only - Admin
Only Bumps - Affine
Point - A point on the secp256k1 elliptic curve in affine coordinates.
- Deposit
Updated Event - Emitted when the admin updates the signature deposit via
chain_signatures::update_deposit. - Error
Response - Error information for failed signature requests.
- Funds
Withdrawn Event - Emitted when the admin withdraws funds via
chain_signatures::withdraw_funds. - GetSignature
Deposit - GetSignature
Deposit Bumps - Initialize
- Initialize
Bumps - Program
State - Program configuration state stored in a PDA.
- Read
Respond - Read
Respond Bumps - Respond
- Respond
Bidirectional Event - Emitted when the MPC network returns execution results for a bidirectional
request via
chain_signatures::respond_bidirectional. - Respond
Bumps - Respond
Error - Respond
Error Bumps - Sign
- Sign
Bidirectional - Sign
Bidirectional Bumps - Sign
Bidirectional Event - Emitted when a bidirectional cross-chain request is made via
chain_signatures::sign_bidirectional. - Sign
Bumps - Signature
- ECDSA signature in affine point representation.
- Signature
Error Event - Emitted when signature generation fails via
chain_signatures::respond_error. - Signature
Requested Event - Emitted when a signature is requested via the
chain_signatures::signinstruction. - Signature
Responded Event - Emitted when the MPC network returns a signature via
chain_signatures::respond. - Withdraw
Funds - Withdraw
Funds Bumps
Enums§
Constants§
- ID_
CONST - Const version of
ID
Statics§
- ID
- The static program ID
Functions§
- check_
id - Confirms that a given pubkey is equivalent to the program ID
- entry
- The Anchor codegen exposes a programming model where a user defines
a set of methods inside of a
#[program]module in a way similar to writing RPC request handlers. The macro then generates a bunch of code wrapping these user defined methods into something that can be executed on Solana. - entrypoint⚠
- Safety
- id
- Returns the program ID
- id_
const - Const version of
ID