> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cantor8.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Transactions and signing

> Submit transfers, create multi-leg DvP swap offers, sign messages, and execute custom DAML commands.

## Standard transfers

Out of the box, the SDK supports connecting a Canton wallet, resolving instruments and accounts, and submitting transfers between parties. This covers the majority of DeFi use cases: payments, settlements, and asset movement across Canton participants.

## Multi-leg swap offers

A multi-leg swap offer describes everything two parties agree to exchange in one coordinated settlement flow. Instead of submitting independent transfers, the creator defines the assets each side must provide, the intended receivers, and the settlement deadline in a single offer.

This structure supports simple token-for-token swaps and exchanges with multiple assets on either side. A common use case is **Delivery versus Payment (DvP)**: one party delivers a tokenized asset while the other provides the corresponding payment.

> [!NOTE]
>
> DvP reduces settlement risk by coordinating delivery and payment. For example, the creator can deliver five tokenized bonds while the acceptor pays 100 units of a cash instrument under the same swap terms.

The offer contains three groups of legs:

| Leg group | Purpose |
| - | - |
| `creatorLegs` | Assets the creator provides to the specified receivers. |
| `acceptorLegs` | Assets the acceptor must provide to the specified receivers. |
| `creatorTransferLegs` | Additional direct transfers the creator includes in the settlement. Use an empty array when none are required. |

Each leg identifies its receiver, instrument, decimal amount, and unique leg ID. `settleBefore` sets the settlement deadline, and `acceptorPartyId` restricts who can accept the offer.

`createSwapOffer()` submits the offer for wallet approval and returns its transaction ID. It does not accept or settle the offer; those steps happen through the subsequent wallet and settlement flow.

```ts theme={null}
const { txId } = await c8.createSwapOffer({
  partyId: "Creator::1220...",
  commandId: crypto.randomUUID(), // Optional
  swap: {
    swapId: crypto.randomUUID(),
    acceptorPartyId: "Acceptor::1220...",
    creatorLegs: [
      {
        receiver: "Acceptor::1220...",
        instrument: {
          admin: "USD-Admin::1220...",
          id: "USD-Instrument::1220...",
        },
        amount: "100.00",
        legId: "creator-usd-leg",
        reason: "USD side of the swap",
      },
    ],
    acceptorLegs: [
      {
        receiver: "Creator::1220...",
        instrument: {
          admin: "Bond-Admin::1220...",
          id: "Bond-Instrument::1220...",
        },
        amount: "5",
        legId: "acceptor-bond-leg",
      },
    ],
    creatorTransferLegs: [],
    settleBefore: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
    meta: {
      orderType: "rfq",
    },
  },
});

console.log("Swap offer submitted:", txId);
```

`partyId` is the creator. `acceptorPartyId` is the only party allowed to accept the offer. Use decimal strings for leg amounts and an ISO 8601 timestamp for `settleBefore`.

## Message signing

Use `signMessage()` to request a wallet signature for an application message. Pass a party ID when a specific account must sign it.

```ts theme={null}
const signature = await c8.signMessage(
  "Accept order 8e2f7c8a",
  "Signer::1220...",
);

console.log("Wallet signature:", signature);
```

Call `signMessage()` from a user gesture because it opens the wallet approval popup.

## Sign and execute custom DAML commands

Use `signAndExecute()` when your transaction is not covered by a high-level SDK method such as `send()` or `createSwapOffer()`. It lets your dApp submit custom operations against DAML templates and choices supported by the connected wallet.

Your dApp builds one or more DAML commands, such as `CreateCommand` or `ExerciseCommand`, and serializes them into `commandsJson`. The wallet displays the supplied `note`, asks the selected party to approve the operation, signs the command set, and submits it for execution.

This method is intended for custom contract workflows implemented for your integration. Use a unique `commandId` for each submission and include any disclosed contracts required to authorize the commands.

```ts theme={null}
signAndExecute(input: {
  note: string;
  partyId: string;
  commandId: string;
  commandsJson: string;
  disclosedContracts: string;
}): Promise<void>;
```

**Parameters**

| Field | Description |
| - | - |
| `note` | Human-readable note shown to the user in the wallet UI. |
| `partyId` | The party submitting the command. |
| `commandId` | Unique idempotency key for this submission (e.g. a UUID). |
| `commandsJson` | JSON-serialized array of DAML commands (`CreateCommand`, `ExerciseCommand`, etc.). |
| `disclosedContracts` | JSON-serialized array of Contracts disclosed to the participant to authorize the command. |

### Example

Submitting a `CreateCommand` for a custom template:

```ts theme={null}
const onSignAndExecuteClick = async () => {
  const input = {
    note: signAndExecuteMessage ?? "Hello from Cantor8 Wallet Connect SDK Demo",
    partyId: selectedAccount,
    commandId: crypto.randomUUID(),
    commandsJson: JSON.stringify([
      {
        CreateCommand: {
          templateId: "#splice-wallet:Splice.Wall..pprovalProposal",
          createArguments: {
            receiver: "9acf24..49ce9d",
            provider: "cantor8-digik-1::122..77f",
            expectedDso: "DSO::122..1a",
          },
        },
      },
    ]),
    disclosedContracts: "",
  };

  c8.signAndExecute(input).catch((e) =>
    console.log("error signing and executing", e, e.data)
  );
};
```

Example of `disclosed_contracts` payload:

```json theme={null}
"disclosed_contracts":
[
    {
        "templateId": "167da4910b0..c93056f2f3bcd",
        "contractId": "0060.77887563880cd00",
        "createdEventBlob": "CgMyLjES7wY..Wk/eLGNgpQNGrdDxjiLIpmGdEB4=",
        "synchronizerId": "global-domain::1220be58..881bb471a"
    }
],
```

## Custom transaction types

Canton's smart contract model (DAML) allows for arbitrarily complex workflows — multi-party agreements, conditional transfers, bespoke financial instruments. If your application requires transaction types beyond standard transfers, the SDK can be extended to support them. This involves aligning on your contract and workflow requirements with the Cantor8 team, who will implement the corresponding support on the C8 backend.

> **[Discuss custom integration](mailto:integrations@cantor8.io?subject=Wallet%20SDK%20custom%20transaction%20types)**
>
> Contact the C8 team at [**integrations@cantor8.io**](mailto:integrations@cantor8.io) to scope custom transaction support for your application.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.