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

# SettlementSale (SVM)

> Reference for the Sonar settlement sale program on Solana.

## Overview

The Sonar settlement sale program is an Anchor-based Solana program for token sales. It follows the same commitment, cancellation, and settlement lifecycle as the EVM [SettlementSale](/sonar/reference/contracts/settlement-sale) contract, adapted for Solana's account model.

Participants commit SPL tokens during the commitment stage. Clearing mechanics and final allocations are computed offchain by Sonar; accepted amounts and refunds are settled onchain.

<Info>
  For standard sale configurations, Sonar deploys and manages this program for you.
</Info>

**Program ID**: `3XxHCh947y1PAMK5y8oecBtaLU7TtTj9r4yMYwzFbJYs`

**Source code**: [solana/](https://github.com/sunrisedotdev/sonar/tree/main/solana)

***

## Program Derived Addresses

All program state lives in PDAs. Seeds use raw bytes — not the UUID string representation.

| Account          | Seeds                                         | Description                 |
| ---------------- | --------------------------------------------- | --------------------------- |
| `SettlementSale` | `["settlement_sale", sale_uuid]`              | Top-level sale state        |
| `EntityState`    | `["entity_state", sale_pda, entity_id]`       | Per-entity commitment state |
| `WalletBinding`  | `["wallet_binding", sale_pda, bidder_pubkey]` | Binds a wallet to an entity |
| Vault            | `["vault", sale_pda]`                         | Holds committed SPL tokens  |

`sale_uuid` and `entity_id` are 16-byte raw UUID values. Entity IDs from the Sonar API may arrive as `0x`-prefixed hex or UUID-formatted strings. Strip the `0x` prefix; if hyphens are present, parse as a UUID, otherwise decode as raw hex.

***

## Instructions

### `place_bid`

Places or updates a bid. Handles first bids and bid increases with the same call.

The instruction verifies the purchase permit signature via instruction introspection of the Ed25519 program. The Ed25519 verify instruction must be the immediately preceding instruction in the same transaction.

See the [integration guide](/sonar/integration-guides/frontend-svm#committing-funds-to-the-sale) for a complete code example.

**Arguments:**

| Argument | Type                                         | Description                                              |
| -------- | -------------------------------------------- | -------------------------------------------------------- |
| `permit` | [`PurchasePermitV3`](#purchasepermitv3-type) | Borsh-encoded permit from Sonar's API                    |
| `amount` | `u64`                                        | Payment tokens to commit, in the token's base unit       |
| `price`  | `u64`                                        | Bid price (for auctions; pass `0` for fixed-price sales) |
| `lockup` | `bool`                                       | Whether the entity opts into token lockup                |

**Accounts:**

| Account                | Writable | Signer | Description                                               |
| ---------------------- | :------: | :----: | --------------------------------------------------------- |
| `bidder`               |    Yes   |   Yes  | The participant's wallet                                  |
| `sale`                 |    Yes   |   No   | The `SettlementSale` PDA                                  |
| `entity_state`         |    Yes   |   No   | The `EntityState` PDA for this entity                     |
| `wallet_binding`       |    Yes   |   No   | The `WalletBinding` PDA for this wallet                   |
| `bidder_token_account` |    Yes   |   No   | Bidder's associated token account for the payment mint    |
| `vault`                |    Yes   |   No   | The vault PDA that holds committed tokens                 |
| `payment_token_mint`   |    No    |   No   | The payment SPL token mint                                |
| `token_program`        |    No    |   No   | SPL Token program                                         |
| `system_program`       |    No    |   No   | System program                                            |
| `instructions`         |    No    |   No   | `Sysvar1nstructions` — required for Ed25519 introspection |

**Bid constraints:**

* Amount can only increase, never decrease
* Price can only increase, never decrease
* Lockup can be enabled but not disabled once set
* The permit must not be expired and the current time must fall within the `opens_at`/`closes_at` window
* The bidder's wallet must match the wallet encoded in the permit

***

## Account Types

### `SettlementSale`

Top-level sale configuration and state. Fetch this account to retrieve `permit_signer` and `vault` before constructing a transaction.

| Field                | Type        | Description                                    |
| -------------------- | ----------- | ---------------------------------------------- |
| `sale_uuid`          | `[u8; 16]`  | The sale UUID (used as a PDA seed)             |
| `permit_signer`      | `PublicKey` | Ed25519 public key that signs purchase permits |
| `vault`              | `PublicKey` | The vault token account address                |
| `payment_token_mint` | `PublicKey` | The accepted payment SPL token mint            |
| `stage`              | `SaleStage` | Current sale stage                             |
| `paused`             | `bool`      | Whether the sale is currently paused           |

### `EntityState`

Per-entity commitment state. One account per entity per sale. Created on the entity's first bid.

| Field            | Type       | Description                              |
| ---------------- | ---------- | ---------------------------------------- |
| `entity_id`      | `[u8; 16]` | The sale-specific entity ID              |
| `current_amount` | `u64`      | Total tokens committed by this entity    |
| `current_price`  | `u64`      | Current bid price                        |
| `lockup`         | `bool`     | Whether the entity has opted into lockup |
| `refunded`       | `bool`     | Whether this entity has been refunded    |

Use `program.account.entityState.fetchNullable(entityStatePDA)` to read commitment progress. A `null` result means no bid has been placed; treat `current_amount` as zero.

### `WalletBinding`

Associates a bidder wallet with an entity. Created on the wallet's first bid; one wallet is bound to exactly one entity per sale.

| Field       | Type        | Description                        |
| ----------- | ----------- | ---------------------------------- |
| `entity_id` | `[u8; 16]`  | The entity this wallet is bound to |
| `sale`      | `PublicKey` | The `SettlementSale` PDA           |

***

## Sale Stages

The program follows the same stage progression as the EVM contract:

```mermaid theme={null}
stateDiagram-v2
    [*] --> Commitment
    Commitment --> Cancellation
    Commitment --> Settlement
    Cancellation --> Settlement
    Settlement --> Done
    Done --> [*]
```

Stage transitions are managed by Sonar. Participants can call `place_bid` during the Commitment stage, cancel during the Cancellation stage, and claim refunds when available. Settlement and pushed refunds are handled by Sonar.

***

## Roles & Permissions

The SVM program uses a bitmask-based role system. Each sale has a single **admin** wallet (set at initialization) with full authority, plus granular roles that can be granted to operator wallets via `grant_role`. The admin implicitly bypasses all role checks — it can call any instruction without an explicit role grant.

### Admin

Full control over the sale. The admin can call any role-gated instruction and is the only wallet that can:

* Grant and revoke roles (`grant_role`, `revoke_role`)
* Withdraw proceeds (`withdraw`, `withdraw_partial`)
* Change the proceeds receiver (`set_proceeds_receiver`)
* Transfer admin authority (`propose_authority` / `accept_authority`)

Admin authority is transferred via a two-step process: the current admin calls `propose_authority` to nominate a new wallet, then the new wallet calls `accept_authority`. Until accepted, the original admin retains full control.

**Held by**: The project (set at initialization).

**Recommended wallet**: Multisig. This role controls funds and role management.

### `Manager`

Manages stage transitions and operational parameters.

**Instructions**:

| Instruction                     | Description                                               |
| ------------------------------- | --------------------------------------------------------- |
| `open_commitment`               | Transitions from PreOpen to Commitment                    |
| `open_cancellation`             | Transitions from Commitment to Cancellation               |
| `open_settlement`               | Transitions from Commitment or Cancellation to Settlement |
| `set_paused`                    | Pauses or unpauses the sale                               |
| `set_claim_refund_enabled`      | Enables or disables self-service refund claims            |
| `set_reduce_commitment_enabled` | Enables or disables partial commitment reduction          |
| `set_max_wallets_per_entity`    | Updates the per-entity wallet limit                       |

**Granted to Sonar at deployment**: Yes.

**Recommended wallet**: Hardware wallet. Stage transitions are time-sensitive and a hardware wallet avoids multisig coordination delays.

### `Settler`

Records final allocations during the Settlement stage.

**Instructions**:

| Instruction      | Description                           |
| ---------------- | ------------------------------------- |
| `set_allocation` | Sets the accepted amount for a wallet |

**Granted to Sonar at deployment**: Yes.

**Recommended wallet**: Software wallet. Settlement is run by Sonar, but a project-controlled wallet provides a backup.

### `SettlementFinalizer`

Finalizes settlement, transitioning the sale from Settlement to Done. The caller provides an `expected_total_accepted` value as a sanity check.

**Instructions**:

| Instruction           | Description                                             |
| --------------------- | ------------------------------------------------------- |
| `finalize_settlement` | Validates total accepted amount and transitions to Done |

**Granted to Sonar at deployment**: No.

**Recommended wallet**: Same multisig as admin. Finalizing settlement is a high-stakes one-time action.

### `Pauser`

Emergency pause that immediately halts all user-facing instructions. The `Pauser` role can only pause the sale — unpausing requires the `Manager` role.

**Instructions**:

| Instruction        | Description     |
| ------------------ | --------------- |
| `set_paused(true)` | Pauses the sale |

**Granted to Sonar at deployment**: Yes.

**Recommended wallet**: One or more software wallets held by on-call team members. Speed is critical for an emergency pause.

### `Refunder`

Processes refunds for participants during the Done stage.

**Instructions**:

| Instruction      | Description                          |
| ---------------- | ------------------------------------ |
| `process_refund` | Pushes a refund to a specific wallet |

**Granted to Sonar at deployment**: Yes.

**Recommended wallet**: Software wallet. Refunds are run by Sonar, but a project-controlled wallet provides a backup.

### `permit_signer`

Not a grantable role — this is the Ed25519 public key stored on the sale account that verifies purchase permit signatures. It is set at initialization and controlled by Sonar. See [Permit Signing](#permit-signing) for details.

### Initial Role Grants

The following roles are granted at initialization. The admin receives implicit access to all operations. Sonar uses two distinct addresses: a management wallet (for operational roles) and a separate signing key (for purchase permits). See the role descriptions above for details on each role.

| Role                  | Admin (project) | Sonar management wallet | Sonar signing key |
| --------------------- | :-------------: | :---------------------: | :---------------: |
| Admin                 |        ✓        |            —            |         —         |
| `Manager`             |        ✓        |            ✓            |         —         |
| `Settler`             |        ✓        |            ✓            |         —         |
| `SettlementFinalizer` |        ✓        |            —            |         —         |
| `Pauser`              |        ✓        |            ✓            |         —         |
| `Refunder`            |        ✓        |            ✓            |         —         |
| `permit_signer`       |        —        |            —            |         ✓         |

Additional project team wallets can be granted roles after deployment via `grant_role` (requires admin).

### Public Instructions (No Role Required)

The following instructions can be called by any wallet:

| Instruction         | Stage        | Description                                      |
| ------------------- | ------------ | ------------------------------------------------ |
| `place_bid`         | Commitment   | Commit funds (requires a valid purchase permit)  |
| `cancel_bid`        | Cancellation | Cancel a bid and reclaim committed funds         |
| `reduce_commitment` | Cancellation | Partially reduce a commitment (if enabled)       |
| `claim_refund`      | Done         | Claim a refund for unaccepted funds (if enabled) |

<Note>
  The project always retains admin authority and full control over the sale, including the ability to grant and revoke all roles. Sonar holds the `permit_signer` key exclusively to authorize eligible participants.
</Note>

***

## Permit Signing

Solana sales use Ed25519 signatures rather than the ECDSA signatures used by EVM sales. The permit is Borsh-encoded using the `PurchasePermitV3` type from the program IDL.

The `permit_signer` field on the `SettlementSale` account holds the Ed25519 public key used to verify permits. This key is controlled by Sonar.

### `PurchasePermitV3` type

| Field                     | Type       | Description                                  |
| ------------------------- | ---------- | -------------------------------------------- |
| `sale_specific_entity_id` | `[u8; 16]` | Sale-specific entity ID                      |
| `sale_uuid`               | `[u8; 16]` | Sale UUID                                    |
| `wallet`                  | `[u8; 32]` | Bidder's wallet public key bytes             |
| `expires_at`              | `i64`      | Unix timestamp when the permit expires       |
| `min_amount`              | `u64`      | Minimum commitment amount                    |
| `max_amount`              | `u64`      | Maximum commitment amount                    |
| `min_price`               | `u64`      | Minimum bid price                            |
| `max_price`               | `u64`      | Maximum bid price                            |
| `opens_at`                | `i64`      | Unix timestamp when the permit becomes valid |
| `closes_at`               | `i64`      | Unix timestamp when the permit closes        |
| `payload`                 | `bytes`    | Arbitrary payload (may be empty)             |

***

## See Also

<CardGroup cols={2}>
  <Card title="Frontend Integration (SVM)" href="/sonar/integration-guides/frontend-svm" icon="browser">
    Step-by-step Solana integration guide with code examples
  </Card>

  <Card title="SettlementSale (EVM)" href="/sonar/reference/contracts/settlement-sale" icon="file-code">
    EVM equivalent contract reference
  </Card>

  <Card title="Purchase Permits" href="/sonar/core-features/purchase-permits" icon="shield-check">
    How Sonar authorizes participation
  </Card>

  <Card title="Sale Lifecycle" href="/sonar/planning/sale-lifecycle" icon="arrows-spin">
    End-to-end sale process
  </Card>
</CardGroup>
