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

# Partner Actions

> Use authenticated, idempotent action records instead of raw quote calls for backend partner integrations.

Partner Actions are the preferred backend-to-backend integration surface for selected partners. They wrap the lower-level quote/build endpoints with:

* API-key authentication
* `Idempotency-Key` protection
* persisted action IDs
* ordered wallet steps
* automatic HyperEVM HYPE gas top-up before signature steps when needed
* transaction hash submission
* polling status
* signed webhook notifications

<Warning>
  Partner API keys are server-side secrets. Do not ship them in a public web app or mobile bundle.
</Warning>

## Create a client

```ts theme={null}
import { createShlpApiClient } from "@arc/shlp-sdk/api";

const shlp = createShlpApiClient({
  baseUrl: "https://portal.signalite.ai",
  partnerApiKey: process.env.SIGNALITE_PARTNER_API_KEY,
});
```

## Create a deposit action

Create a Signalite deposit action only after the wallet already has HyperEVM
USDC. For cross-chain funding, Arc/partner code should first use Relay or its
own funding rail to move USDC from the selected source network into the user's
EVM wallet on HyperEVM, then create the Partner Action for the actual received
HyperEVM USDC amount.

```ts theme={null}
import { parseUsdc } from "@arc/shlp-sdk";

const action = await shlp.createPartnerDepositAction({
  idempotencyKey: `user:${userId}:deposit:${clientRequestId}`,
  amount: parseUsdc("1"),
  account: userAddress,
  receiver: userAddress,
  slippageBps: 50,
});
```

Use the typed helpers first: `createPartnerDepositAction`,
`createPartnerRedeemInstantAction`, `createPartnerRedeemAsyncAction`,
`createPartnerClaimAction`, `createPartnerCancelAction`, and
`createPartnerFulfillAction`. The generic `createPartnerAction` remains an
escape hatch, but typed helpers avoid malformed `body` payloads.

The response contains `steps`. Send them in order through the user's wallet:

```ts theme={null}
for (const step of action.steps) {
  if (!step.tx) continue;

  const hash = await wallet.sendTransaction(step.tx);
  await waitForReceipt(hash);

  if (step.refreshQuoteAfterConfirm) {
    // Approval changed allowance. Create a fresh action/quote before sending
    // the vault deposit transaction.
  }
}
```

Signalite checks the action wallet's HYPE balance while creating the Partner Action. If the wallet needs gas and the top-up service is enabled, Signalite sends a small HYPE drip before returning `requires_signature` steps. If gas sponsorship is disabled or unfunded, action creation fails closed instead of handing the partner wallet steps that cannot execute.

## Cross-chain funding rule

Signalite does not bridge source-chain USDC inside Partner Actions. The
Partner Action wallet steps are only for HyperEVM chain `999`.

Use config to discover supported funding sources:

```ts theme={null}
const config = await shlp.getConfig();
const funding = config.deposit.funding;
```

Arc integration rule:

1. Quote/execute funding from the selected source network to HyperEVM USDC.
2. Wait for the user's HyperEVM USDC balance to reflect the actual received amount.
3. Create the Signalite deposit Partner Action.
4. Execute ordered Signalite steps.
5. Submit only the final Signalite V2 pipe transaction hash.

Do not submit approval hashes, Relay/funding hashes, source-chain hashes, or
wrong-chain hashes to `POST /api/v1/partner/actions/{id}/submit`.

## Cross-chain withdrawal receive rule

Signalite withdrawals settle on HyperEVM first. Partners can request the user's
desired receive chain by passing `receiveChainId` on withdrawal Partner Actions:

```ts theme={null}
const action = await shlp.createPartnerRedeemAsyncAction({
  idempotencyKey: `user:${userId}:withdraw:${clientRequestId}`,
  shares: sharesRaw,
  account: userAddress,
  slippageBps: 50,
  receiveChainId: 8453, // Base USDC after HyperEVM settlement
});
```

`receiveChainId` is optional and defaults to `999` for HyperEVM. Valid values
come from `GET /api/v1/config` at `withdraw.supportedDestinations`.

For non-HyperEVM destinations, the Partner Action metadata includes
`metadata.withdrawal.postSettlementBridge.required=true`. The wallet step is
still the HyperEVM redeem or claim transaction. After that transaction confirms
and the user has HyperEVM USDC, Arc/partner code runs the Relay bridge to the
requested destination.

For queued withdrawals, persist the selected `receiveChainId` with the pending
redeem in partner state and pass the same value again when creating the later
claim action:

```ts theme={null}
await shlp.createPartnerClaimAction({
  idempotencyKey: `user:${userId}:claim:${redeemId}`,
  id: redeemId,
  account: userAddress,
  receiver: userAddress,
  receiveChainId: 8453,
});
```

Do not submit Relay bridge hashes to Signalite. `submitPartnerAction` accepts
only the final successful HyperEVM Signalite V2 pipe transaction hash.

Queued withdraw fulfillment is FIFO. A later smaller withdrawal must remain
pending behind an earlier larger request until the keeper can fulfill the
earlier request or the earlier user cancels.

## Submit the transaction hash

After the wallet sends the primary transaction:

```ts theme={null}
await shlp.submitPartnerAction({
  id: action.id,
  txHash,
});
```

Then poll:

```ts theme={null}
const current = await shlp.getPartnerAction(action.id);
```

## Supported action kinds

| Action           | Endpoint                                      |
| ---------------- | --------------------------------------------- |
| `deposit`        | `POST /api/v1/partner/actions/deposit`        |
| `redeem_instant` | `POST /api/v1/partner/actions/redeem-instant` |
| `redeem_async`   | `POST /api/v1/partner/actions/redeem-async`   |
| `claim_redeem`   | `POST /api/v1/partner/actions/claim`          |
| `cancel_redeem`  | `POST /api/v1/partner/actions/cancel`         |
| `fulfill_redeem` | `POST /api/v1/partner/actions/fulfill`        |

## Idempotency

Every create request must include a stable `Idempotency-Key`. Reusing the same key for the same action returns the original action. Reusing it for a different action returns `IDEMPOTENCY_CONFLICT`.

Good key examples:

```text theme={null}
user_123:deposit:client_request_456
wallet_0xabc:claim:redeem_7
```

## Raw HTTP

```http theme={null}
POST /api/v1/partner/actions/deposit
Authorization: Bearer <partner_api_key>
Idempotency-Key: user_123:deposit:client_request_456
Content-Type: application/json

{
  "amountRaw": "1000000",
  "account": "0x...",
  "receiver": "0x...",
  "slippageBps": 50
}
```

## Readiness rule

Partner Actions do not bypass product readiness. Still gate UI with `/api/v1/health`, and treat quote/action business errors as product states, not generic crashes.
