The flow

Step by step
- A job is created on Solana. The job commits to an off-chain API configuration via
apiConfigHash; only the hash is stored on-chain. The job’s identity isjobId = keccak256("MOLPHA_JOB_V1" || owner || apiConfigHash). - A round is requested. A gateway round runs against the current on-chain registry version: a deterministically selected subset of nodes independently fetches the API, converges on a canonical value, and produces a single aggregate Schnorr signature.
- The result is a self-contained payload. A
DataUpdate(jobId, registryVersion, signaturesRequired, value, canonicalTimestamp) plus aSchnorrSignature(scalars, commitment address, signers bitmap). The signers bitmap is bound into the signed message — the signer set cannot be chosen after the fact. - Any chain verifies it. Each verifier re-derives the eligible signer selection from the payload itself, reconstructs the coalition public key as the plain EC sum of the actual signers’ keys, and checks one Schnorr signature. The same payload verifies on Solana, EVM, and Starknet.
- Consumption. On Solana,
submit_data_updatewrites the verified value to aFeedaccount anyone can read;verify_data_updateverifies statelessly and returns the value. On EVM and Starknet, your contract callsverify()and applies its own freshness policy.
Key properties
- Pull-native. Rounds run on demand. There is no heartbeat to fund and no per-chain feed maintenance.
- One signature, every chain. No
chainIdin the signed message; identical domain-separated hashing on every verifier. - Selection is verifiable on-chain. The eligible signer group is derived from
(jobId, registryVersion, canonicalTimestamp)— a caller cannot grind a favorable signer set. - Verification is stateless on EVM/Starknet. A successful
verify()proves who signed what. Freshness, replay protection, and value bounds are the consumer’s policy.