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

# Transfer Offer

## What Is a Transfer Offer?

On Canton, asset transfers are modeled as **transfer offers** rather than immediate, unilateral transactions like those found on most public blockchains.

A transfer offer represents a **two-step, consent-based transfer**:

1. The sender creates an offer specifying the recipient and amount.
2. The recipient explicitly **accepts or rejects** the offer.

This design enables privacy-preserving, compliant, and deterministic settlement between known parties—an important distinction from public blockchains where transactions are typically broadcast and finalized immediately.

## Transfer Offer Lifecycle

<Steps>
  <Step title="Sender creates a transfer offer">
    The sender creates a transfer offer specifying the recipient Canton wallet, token, and amount. The specified amount of the asset is locked and cannot be used while the offer is pending.
  </Step>

  <Step title="Offer is received by destination wallet">
    The transfer offer becomes visible to the recipient’s Canton wallet
  </Step>

  <Step title="Accept or reject the offer">
    The recipient explicitly accepts or rejects the offer. Accepting executes the transfer, while rejecting declines it with no asset movement.
  </Step>
</Steps>

## Create Transfer Offer

A transfer offer is created by the sender to propose transferring a specified amount of token to a Canton wallet. The offer remains pending until the recipient takes action.

Creating a transfer offer utilizes the existing on-chain transfer functionality. For more details please checkout [Creating Single Transfers](https://docs.hifi.com/transactions/transfers#creating-single-transfers)

## Retrieving Transfer Offers

HIFI provides endpoints to retrieve transfer offers for a wallet, including all incoming offers or a specific offer.

### Get All Incoming Transfer Offers

Retrieve all transfer offers for a specific wallet using wallet id.

**Request**

```shellscript theme={null}
curl -X GET "https://production.hifibridge.com/v2/wallets/:walletId/offers" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
```

**Response**

```json theme={null}
{
  "count": 1,
  "records": [
    {
      "id": "3b6f7b9a-1f3a-4c8c-9c51-82f3e1c9a111",
      "status": "RECEIVED",
      "amount": "100.00",
      "currency": "usdcx",
      "source": { 
		"party": "HIFI-validator-1::1220c44096409d3244021ae82992ccae3a1208fa79cacf450760b6f2cd9dfee2daa6" 
	  },
      "destination": {
        "userId": "7c91b1e0-0a43-4f7c-9c88-3eaa9f41c9dd",
        "userWalletId": "9d1f1a0e-2d84-4e3b-9c92-6a9b6a7e1f23",
        "party": "HIFI-validator-1::1220e636b510224be2c15b4436c0eb72558fdd6a93268b3605fad7f27f58192910e6"
      },
      "creationTransactionHash": "122095966f1d10cbf4de93e55fd0ecca745b7aba0ae48647c9ae298dbc6f57de9ef8",
      "executionTransactionHash": null,
      "createdAt": "2026-02-02T18:21:00Z",
      "updatedAt": "2026-02-02T18:21:00Z",
      "expiresAt": "2026-02-03T18:21:00Z"
    },
  ],
  "nextCursor": "2026-02-02T18:22:00Z"
}
```

### Get a Specific Transfer Offer

Retrieve details for a single transfer offer by ID.

**Request**

```shellscript theme={null}
curl -X GET "https://production.hifibridge.com/v2/wallets/:walletId/offers/:offerId" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
```

**Response**

```json theme={null}
{
  "id": "3b6f7b9a-1f3a-4c8c-9c51-82f3e1c9a111",
  "status": "RECEIVED",
  "amount": "100.00",
  "currency": "usdcx",
  "source": { 
	"party": "HIFI-validator-1::1220c44096409d3244021ae82992ccae3a1208fa79cacf450760b6f2cd9dfee2daa6" 
  },
  "destination": {
    "userId": "7c91b1e0-0a43-4f7c-9c88-3eaa9f41c9dd",
    "userWalletId": "9d1f1a0e-2d84-4e3b-9c92-6a9b6a7e1f23",
    "party": "HIFI-validator-1::1220e636b510224be2c15b4436c0eb72558fdd6a93268b3605fad7f27f58192910e6"
  },
  "creationTransactionHash": "122095966f1d10cbf4de93e55fd0ecca745b7aba0ae48647c9ae298dbc6f57de9ef8",
  "executionTransactionHash": null,
  "createdAt": "2026-02-02T18:21:00Z",
  "updatedAt": "2026-02-02T18:21:00Z",
  "expiresAt": "2026-02-03T18:21:00Z"
}
```

## Action Transfer Offer

Once a transfer offer has been received, the recipient can **accept or reject** the offer. The choice determines whether the asset will be credited into recipient's wallet or not.

<Note>
  A transfer offer must be **accepted or rejected** by the recipient before it expires. Once the expiration time passes, the offer is no longer valid.
</Note>

### Accept a Transfer Offer

Accepting a transfer offer executes the asset transfer and finalizes the transaction.

* The transfer moves the locked asset to the recipient’s wallet.
* The offer status will terminiate at `ACCEPTED`.

**Request**

```shellscript theme={null}
curl -X POST "https://production.hifibridge.com/v2/wallets/<walletId>/offers/<offerId>/accept" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
```

<Accordion title="Response">
  ```json theme={null}
  {
    "id": "3b6f7b9a-1f3a-4c8c-9c51-82f3e1c9a111",
    "status": "PENDING",
    "amount": "100.00",
    "currency": "usdcx",
    "source": { 
  	"party": "HIFI-validator-1::1220c44096409d3244021ae82992ccae3a1208fa79cacf450760b6f2cd9dfee2daa6" 
    },
    "destination": {
      "userId": "7c91b1e0-0a43-4f7c-9c88-3eaa9f41c9dd",
      "userWalletId": "9d1f1a0e-2d84-4e3b-9c92-6a9b6a7e1f23",
      "party": "HIFI-validator-1::1220e636b510224be2c15b4436c0eb72558fdd6a93268b3605fad7f27f58192910e6"
    },
    "creationTransactionHash": "122095966f1d10cbf4de93e55fd0ecca745b7aba0ae48647c9ae298dbc6f57de9ef8",
    "executionTransactionHash": null,
    "createdAt": "2026-02-02T18:21:00Z",
    "updatedAt": "2026-02-02T18:21:00Z",
    "expiresAt": "2026-02-03T18:21:00Z"
  }
  ```
</Accordion>

**Behavior**

* Transaction status changes from `PENDING` → `ACCEPTED`
* `executionTransactionHash` is set once the transfer is executed
* Your system can listen to the `WALLET.OFFER.ACCEPTED` webhook to trigger downstream actions

### Reject a Transfer Offer

Rejecting a transfer offer declines the proposed transfer.

* The locked asset is released back to the sender.
* The offer status updates to `REJECTED`.

#### Request

```text theme={null}
curl -X POST "https://production.hifibridge.com/v2/wallets/<walletId>/offers/<offerId>/reject" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
```

<Accordion title="Response">
  ```json theme={null}
  {
    "id": "3b6f7b9a-1f3a-4c8c-9c51-82f3e1c9a111",
    "status": "PENDING",
    "amount": "100.00",
    "currency": "usdcx",
    "source": { 
  	"party": "HIFI-validator-1::1220c44096409d3244021ae82992ccae3a1208fa79cacf450760b6f2cd9dfee2daa6" 
    },
    "destination": {
      "userId": "7c91b1e0-0a43-4f7c-9c88-3eaa9f41c9dd",
      "userWalletId": "9d1f1a0e-2d84-4e3b-9c92-6a9b6a7e1f23",
      "party": "HIFI-validator-1::1220e636b510224be2c15b4436c0eb72558fdd6a93268b3605fad7f27f58192910e6"
    },
    "creationTransactionHash": "122095966f1d10cbf4de93e55fd0ecca745b7aba0ae48647c9ae298dbc6f57de9ef8",
    "executionTransactionHash": null,
    "createdAt": "2026-02-02T18:21:00Z",
    "updatedAt": "2026-02-02T18:21:00Z",
    "expiresAt": "2026-02-03T18:21:00Z"
  }
  ```
</Accordion>

#### Behavior

* Transaction status changes from `PENDING` → `REJECTED`
* `executionTransactionHash` is set once the rejection is recorded
* Your system can listen to the `WALLET.OFFER.REJECTED` webhook to trigger downstream actions

### Withdraw a Transfer Offer

The sender (i.e., the creator of the transfer offer) may withdraw or cancel the transfer offer at any time before it is accepted or rejected.

If a transfer offer is not explicitly withdrawn, it will be locked by the protocol and cannot be used for future transfers.

To withdraw a transfer offer, you must provide the **original on-chain transaction ID**.

**Request**

```shellscript theme={null}
curl -X POST "https://production.hifibridge.com/v2/wallets/transfers/<transferId>/cancel" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
```

<Accordion title="Response">
  ```json theme={null}
  {"message": "Transaction cancelled in progress"}
  ```
</Accordion>

**Behavior**

* The transaction cancellation is broadcast synchronously.
* Once the offer withdrawal is confirmed, the original on-chain transaction will transition to a **CANCELLED** state.
* Your system can listen to the `WALLET.OFFER.WITHDRAWN` webhook to trigger downstream actions

## Offer Statuses

Each Canton transfer offer has a `status` that reflects its current state:

| Status      | Description                                                                                                            |
| ----------- | ---------------------------------------------------------------------------------------------------------------------- |
| `RECEIVED`  | The offer has been received by the destination wallet and is ready to be acted upon.                                   |
| `PENDING`   | The offer is currently in the process of being accepted or rejected.                                                   |
| `ACCEPTED`  | The recipient has accepted the offer. The transfer has been executed and the asset has been moved.                     |
| `REJECTED`  | The recipient has rejected the offer. No transfer occurred, and the locked asset has been released back to the sender. |
| `WITHDRAWN` | The transfer offer has been canceled by the sender.                                                                    |
| `EXPIRED`   | The transfer offer has already expired and can no longer be accepted or rejected.                                      |

## Webhook Notifications

HIFI sends webhook events to notify your system of transfer offer state changes.

| Webhook Event            | Description                                                                                     |
| ------------------------ | ----------------------------------------------------------------------------------------------- |
| `WALLET.OFFER.RECEIVED`  | A new transfer offer has been received by the destination wallet and is ready to be acted upon. |
| `WALLET.OFFER.PENDING`   | The transfer offer is currently being accepted or rejected.                                     |
| `WALLET.OFFER.ACCEPTED`  | The recipient has accepted the offer. The transfer has been executed and the asset moved.       |
| `WALLET.OFFER.REJECTED`  | The recipient has rejected the offer. No transfer occurred, and the locked asset is released.   |
| `WALLET.OFFER.WITHDRAWN` | The transfer offer has been canceled by the sender.                                             |
| `WALLET.OFFER.EXPIRED`   | The transfer offer has already expired and can no longer be accepted or rejected.               |

<Note>
  Listen to the `WALLET.OFFER.RECEIVED` webhook events to be notified whenever a new incoming transfer offer is available for action.
</Note>

## Getting Help

* 📧 **Email:** [support@hifi.com](mailto:support@hifi.com)
* 💬 **Slack:** Message us in our shared Slack channel

## Related Resources

* [Wallet Transfers](/transactions/transfers) - Single wallet transfers
* [USDCx Bridging](/docs/features/canton/usdcx-bridging) - Bridge USDCx on Canton
* [Webhooks](/webhooks) - Real-time approval notifications
* [API Reference](https://docs.hifi.com/api/authentication) - Complete endpoint documentation
