Skip to main content
Cross-chain payment turns “pay USDC on Sui” into “a valid signature on another chain.” This page explains the parts that make that safe.

Components

dWallet (Ika 2PC-MPC)

A wallet whose private key is split across Ika’s MPC network. It can sign for other chains, but no single party — including Tentacle Pay — ever holds the whole key.

Move contract

The tentaclepay package on Sui. It custodies the DWalletCap, collects the USDC payment, and routes the signing request to Ika’s coordinator. See Smart contracts.

Verifier

An off-chain service that attests each signing request. The contract refuses to sign without a fresh, valid attestation.

Coordinator

Ika’s DWalletCoordinator — the on-chain entry point that runs the threshold signing protocol and returns the signature.

The flow

1

The agent builds the destination payment

The x402 client produces the payment authorization for the destination chain (for example, an EVM transferWithAuthorization) and signs its half — the centralized signature.
2

The verifier attests the request

The agent sends the request to the verifier, which returns an Ed25519 signature over a digest binding this exact call: the protocol, signer, coordinator, amount, message, and an expiry.
3

pay_and_sign runs on Sui

The agent calls pay_and_sign, paying USDC and passing the message, its centralized signature, and the verifier attestation. The contract checks the attestation, takes the payment, and requests the threshold signature from the coordinator.
4

Ika produces the signature

The coordinator consumes a pre-funded presign and runs the 2PC-MPC protocol, producing a signature valid on the destination chain.
5

The payment settles on the destination

The signed authorization is submitted to the destination chain, paying the service.

Why the verifier attestation

The contract will only ask the dWallet to sign a message that the verifier has approved. The verifier signs the digest:
keccak256(
  "pay_and_sign"
    || protocol.id || signer.id || coordinator.id
    || payment.value || message || keccak256(message_centralized_signature)
    || valid_before
)
Binding all of these into one digest gives three guarantees:
  • No tampering — change the amount, message, or any object id, and the attestation no longer verifies.
  • No replay — the digest commits to this specific call, so an attestation can’t be reused for another.
  • Bounded lifetimevalid_before is checked against Sui’s on-chain Clock, so a stale attestation is rejected.
On-chain, the contract rebuilds this digest from the call’s parameters and verifies it against the verifier’s public key stored in the Protocol object. The key can be rotated by the protocol admin.

Presigns and sponsored fees

Threshold signing is faster when part of the work is done ahead of time. The contract keeps a pool of single-use presigns; each signature consumes one, and the pool is refilled with add_presigns. It also holds sponsored IKA and SUI fee pools so callers don’t have to supply the protocol fees themselves — anyone can top these up with deposit_ika and deposit_sui.

Trust model

  • The dWallet key is never reconstructed; signatures come from Ika’s MPC protocol.
  • The Move contract is the only thing that can approve a message for the dWallet, and it does so only against a valid verifier attestation.
  • The verifier authorizes which payments may be signed; it cannot move funds or sign on its own.
  • USDC paid into the contract accumulates in an admin-gated vault — it funds the destination-side settlement.

Next steps

Smart contracts

The tentaclepay Move module in detail.