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

# Referral staking & partner commission

> Attribute stakes to your partner address with stakeAlphWithReferral, and how partner commission is calculated and paid.

export const VersionBanner = ({network = 'mainnet', products = [], lang = 'en'}) => {
  const SDK_VERSION = '1.0.2';
  const ADDRESSES = {
    mainnet: {
      cpmm: {
        Router: 'ze15rnAwTyVCPnDhN7J8An3SvNeWBsZHAVMeBx1ehXeP',
        TokenPairFactory: '24CXRLvj1QiDH6riwr1EPERG7BcduHKZtktygbq97MfYb'
      },
      clmm: {
        PoolFactory: '24gqd4DMQXVzjm5QDAGxUtYupx3WM2PSu3vZUseuBCV9h',
        PositionManager: 'vFyKSqnJHS9MicrojBcLgztyRFqhS4hB349Ci3LJCELw'
      },
      staking: {
        XAlphToken: '225WevmFp5ZgzPsyVJTvyp2v2uyKrvp329HfrVmzffnWj',
        RewardFeeCollector: '22CE7vG6u64zjjsLZLxeJqQuPDydjPvbP9iG1d861j2G7'
      }
    },
    testnet: {
      cpmm: {
        Router: 'xaueT8kPMvpnaFJEfHv6CJLgqsSPpoNmHjF1QgTxoF9R',
        TokenPairFactory: '29hdd9b9Gp7oXuamwHKfUqBaRXP487HoeTcutS3RhZJEj'
      },
      clmm: {
        PoolFactory: 'z2QFT7qBQrfm8UwAYG3VHWoHs7B56ZDFNdSCcDu5j53m',
        PositionManager: '21p6egW8d6FEyVVuH17WqvHCARsCsD61GcBmeCr75XdGT'
      },
      staking: {
        XAlphToken: '23psDicimC5VdpM56wrgqgCzQzcyXWGCkQGSYWbtZAPRq',
        RewardFeeCollector: '29qQ1LPJ5uqawRviXLVDMeo19JUygRrNNTQy5RUBh817D'
      }
    }
  };
  const EXPLORERS = {
    mainnet: 'https://explorer.alephium.org/addresses/',
    testnet: 'https://testnet.alephium.org/addresses/'
  };
  const LABELS = {
    en: {
      sdk: 'SDK',
      network: 'Network',
      contracts: 'Contracts',
      all: 'All addresses',
      allNetworks: 'mainnet · testnet · devnet',
      devnet: 'Local deployment (addresses vary per devnet)'
    },
    zh: {
      sdk: 'SDK 版本',
      network: '网络',
      contracts: '合约',
      all: '全部地址',
      allNetworks: 'mainnet · testnet · devnet',
      devnet: '本地部署（每个 devnet 的地址不同）'
    },
    fr: {
      sdk: 'SDK',
      network: 'Réseau',
      contracts: 'Contrats',
      all: 'Toutes les adresses',
      allNetworks: 'mainnet · testnet · devnet',
      devnet: 'Déploiement local (adresses propres à chaque devnet)'
    }
  };
  const t = LABELS[lang] ?? LABELS.en;
  const contractsPage = lang === 'en' ? '/reference/contracts' : `/${lang}/reference/contracts`;
  const short = a => `${a.slice(0, 6)}…${a.slice(-4)}`;
  const entries = [];
  const addrs = ADDRESSES[network];
  if (addrs) {
    for (const p of products) {
      for (const [name, address] of Object.entries(addrs[p] ?? ({}))) entries.push({
        name,
        address
      });
    }
  }
  let contractsCell;
  if (network === 'devnet' && products.length > 0) {
    contractsCell = <span>{t.devnet}</span>;
  } else if (entries.length > 0) {
    contractsCell = entries.map(({name, address}, i) => <span key={name}>
        {i > 0 && <span className="mx-1 opacity-50">·</span>}
        {name}{' '}
        <a href={EXPLORERS[network] + address} target="_blank" rel="noreferrer" title={address}>
          <code>{short(address)}</code>
        </a>
      </span>);
  }
  const row = (label, value) => <div className="flex flex-wrap gap-x-2">
      <span className="font-semibold min-w-[5.5rem]">{label}</span>
      <span className="flex-1 min-w-0 break-words">{value}</span>
    </div>;
  return <div className="not-prose mb-6 rounded-xl border border-zinc-950/10 dark:border-white/10 bg-zinc-50 dark:bg-white/5 px-4 py-3 text-sm leading-6 text-zinc-700 dark:text-zinc-300">
      {row(t.sdk, <code>@alephium/powfi-sdk@{SDK_VERSION}</code>)}
      {row(t.network, network === 'all' ? t.allNetworks : network)}
      {contractsCell && row(t.contracts, <span>
            {contractsCell}
            <span className="mx-1 opacity-50">·</span>
            <a href={contractsPage}>{t.all} →</a>
          </span>)}
    </div>;
};

<VersionBanner network="mainnet" products={['staking']} lang="en" />

Partners can bring stakers to Powfi and earn a share of the yield those stakers receive. Attribution happens on-chain through the `referral` argument of a stake. The commission is calculated off-chain and paid by the Powfi team.

<Warning>
  **Contact the Powfi team before you use a referral address.** The contract accepts any address as `referral`, but commission is only paid to partners who have an agreement with the team. The agreement sets your partner address, commission rate, settlement period, and payment method. Stakes tagged with an address the team doesn't know about may not be eligible for commission.
</Warning>

## How it works

<Steps>
  <Step title="Register your partner address with the team">
    Agree on the partner address you will use, your commission rate (y%), and the settlement schedule.
  </Step>

  <Step title="Stake with your address as referral">
    Your frontend or integration calls `stakeAlphWithReferral` with your partner address. Use the same address for every stake.
  </Step>

  <Step title="Yield accrues to your stakers">
    The xALPH exchange rate rises as protocol rewards are distributed. Your stakers earn that yield like any other xALPH holder.
  </Step>

  <Step title="Settlement and payment">
    Each period, the team computes the yield earned by the xALPH attributed to you and pays you y% of it in ALPH.
  </Step>
</Steps>

## Stake with a referral

```ts theme={null}
import { Powfi } from '@alephium/powfi-sdk'
import { ONE_ALPH } from '@alephium/web3'

const powfi = Powfi.load({ networkId: 'mainnet', signer }) // the staker's wallet
const PARTNER_ADDRESS = '<your registered partner address>'

const result = await powfi.staking.stakeAlphWithReferral(100n * ONE_ALPH, PARTNER_ADDRESS)
console.log(result.txId)
```

The staker pays nothing extra for the referral. The transaction is the same as `stakeAlph` (it attaches `amount + MINIMAL_CONTRACT_DEPOSIT` ALPH), and the staker receives the same amount of xALPH.

<Note>
  The official Powfi frontend does not currently accept a referral parameter. To attribute stakes to your address, build your own staking page or integration that calls `stakeAlphWithReferral`.
</Note>

### What the contract does with `referral`

* **No validation, no registration on-chain.** `XAlphToken.stake(amount, referral)` accepts any address and only records it in the `Staked` event.
* **The referral receives no tokens.** Because nothing is transferred to it, the referral does not appear in the explorer's transaction view. It is only visible in the event.
* **The stake must come from a wallet.** `stake` requires the caller to be an asset (wallet) address, so contracts cannot stake on a user's behalf.
* The event is `Staked(to, referral, alphAmount, xAlphAmount)`: staker, referral, ALPH deposited, xALPH minted.

## Verify attribution

Anyone can check which referral a stake was attributed to by reading the transaction's events from a node:

```ts theme={null}
const xAlphAddress = powfi.staking.getConfig().xAlphTokenAddress
const { events } = await powfi.nodeProvider.events.getEventsTxIdTxid(txId)

// Staked is the first event declared by XAlphToken (eventIndex 0)
const staked = events.find((e) => e.contractAddress === xAlphAddress && e.eventIndex === 0)
const [to, referral, alphAmount, xAlphAmount] = staked!.fields.map((f) => f.value)
```

Groupless addresses may appear with a `:<group>` suffix in the event. That is the same address.

## How commission is calculated

For each settlement period:

1. **Attributed xALPH**: sum the `xAlphAmount` of every `Staked` event whose `referral` is your address.
2. **Rate increase**: `yieldRateDelta = rate(end of period) − rate(end of previous period)`, where `rate = totalDepositedAlph / totalXAlphSupply` (see [Staking](/modules/staking)).
3. **Gross yield**: `attributed xALPH × yieldRateDelta`, in ALPH.
4. **Your commission**: `gross yield × y%`.

Things that affect the numbers:

* **Only the xALPH minted at stake time counts.** Later xALPH transfers and unstakes are not tracked.
* **Staking does not move the rate.** New stakes mint xALPH at the current rate. The rate only rises when rewards are deposited.
* **Rewards depend on protocol revenue.** The rate rises when `RewardFeeCollector.distributeRewards()` runs. It distributes `totalDepositedAlph × rewardRate × elapsed time / 1 year` (an annual rate), capped by the ALPH the collector holds from trading fees. The treasury share and the burn share are taken out first, and the rest raises the xALPH rate. If there is little trading volume, there is little yield to share.

## Payment

Commission is an off-chain amount owed to you, not an on-chain transfer triggered by the stake. The team pays it in ALPH from the treasury according to your agreement. Because every input (the `Staked` events and the xALPH rate) is public on-chain, you can recompute your commission independently. Ask the team for the verification page that lists your settlements.

## Referral commission vs integrator fees

These are two separate mechanisms:

| | Referral commission (this page) | [Integrator fees](/guides/integrator-fees) |
| - | - | - |
| Applies to | Staking (`stakeAlphWithReferral`) | Swaps (`cpmm.swap`, `clmm.swap`) |
| Who pays | Powfi, from protocol yield | The user, on top of the swap |
| Calculated | Off-chain, per settlement period | On-chain, amount set by the integrator |
| Paid | By the team, according to the agreement | Immediately, in the same transaction |
| Needs team agreement | Yes | No |


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