Guides
Gamma
Dollar-valued service credits minted by burning a subnet's alpha, held in deposits keyed by API-key hotkeys and spent by each deposit's spender.
Gamma is a credit a subnet can accept as payment for its service, valued in US dollars. Once gamma is enabled network-wide and on a subnet, a coldkey mints that subnet's gamma by burning its alpha, bought with TAO or taken from stake. One gamma is minted for each dollar the burned alpha is worth.
Gamma is held in deposits. Each deposit belongs to a coldkey and is keyed by a hotkey, which signs the customer's requests to the service, so the hotkey works as an API key. The deposit's spender spends it as it serves those requests.
Before opening a deposit, associate the API-key hotkey with the minting coldkey
using try_associate_hotkey (or register the hotkey). Only that coldkey can open
a deposit at the hotkey, including by moving gamma into a new deposit.
Gamma cannot be transferred to another coldkey or converted back into alpha or TAO. Amounts are in gamma, with 10^9 units per gamma.
| Role | Can |
|---|---|
| Coldkey | mint into its deposits, move gamma between them, set each deposit's spender and daily spend cap, close empty deposits |
| Hotkey | nothing on chain; it signs requests to the service |
| Validator or subnet owner hotkey | publish a service and its spender on its subnet, signed by its coldkey |
| Spender | spend the deposits that name it, directly or through a GammaSpend proxy |
| Subnet owner | enable gamma on its subnet with gamma_enabled; spender of the deposits a mint opens while it owns the subnet, unless its hotkey's service names another or a lease owns it |
| Lease beneficiary | enable gamma through its SubnetLeaseBeneficiary proxy; spender of the deposits a mint opens while its lease owns the subnet, unless the subnet owner hotkey's service, which it publishes through that proxy, names another |
| Root | enable gamma network-wide and on any subnet but root, and set the TAO/USD price oracle |
| Oracle | feed the TAO/USD price |
Minting
Minting needs gamma enabled on the subnet and a fresh
TAO/USD price. Mint with TAO into a deposit at a fresh
hotkey, for a service the subnet lists with services:
btcli wallet new-hotkey -H API_KEY
btcli wallet associate-hotkey --hotkey API_KEY
btcli query services --netuid 51
btcli gamma mint --netuid 51 --hotkey API_KEY --amount-tao 10 --service-hotkey SERVICE_HOTKEYquote = await client.gamma.quote_mint_gamma(netuid=51, amount_tao=10)
await client.execute(bt.AssociateHotkey(hotkey_ss58=api_key), wallet)
await client.execute(
bt.MintGamma(netuid=51, hotkey_ss58=api_key, amount_tao=10, service_hotkey_ss58=service), wallet
)--service-hotkey names the spender the service publishes, so the service can
spend the deposit.
mint-gamma buys alpha with the TAO and burns it, with
the same pool and flow accounting as stake-burn, and
creates no stake position.
mint-gamma-with-stake burns stake you
already hold instead:
btcli gamma mint-with-stake --netuid 51 --hotkey API_KEY --origin-hotkey VALIDATOR --amount-alpha 100 --service-hotkey SERVICE_HOTKEY--amount-alpha all burns the whole stake.
The burned alpha is valued at the lower of two prices:
TAO value = alpha × min(gamma price, spot price)
gamma = TAO value × TAO/USD priceEvery subnet but root keeps a gamma price, whether or not gamma is enabled. Registration sets it to the median subnet alpha price, which the new pool is created at; a subnet registered before gamma starts at its spot price. Each block it falls to the spot price at once and rises toward it by ln 2 / 600 of the gap, so the gap halves every 600 blocks, about 2 hours. A rise is at most ln 2 / 600 of the gamma price itself, so however far spot jumps, the gamma price at most doubles every 600 blocks. The spot price is read before the mint trades. Alpha is valued at these prices, not at what selling it would return, so a burn that is large for the pool is worth more than its sale.
The SDK quotes the mint first and fails it if the minted gamma would fall more
than rate_tolerance (5% by default) below the quote. The with-stake quote
assumes the whole amount is burned; the SDK quotes no more than the stake you
hold. Once the mint runs, result.data["minted"] holds the deposit's
hotkey_ss58, spender_ss58 and daily_spend_cap_gamma, and the
alpha_burned, tao_value and gamma minted, as exact decimal strings.
A mint fails with GammaDisabled while
gamma is off network-wide or on the subnet. No other call checks these
switches, so turning one off stops new mints only, and existing deposits can
still be spent, moved and closed. A mint also fails with
AmountTooLow below 0.1 gamma, with
SubtokenDisabled on a subnet whose
subtoken is not enabled, and with
SlippageTooHigh below its minimum. A TAO
mint above the add-stake swap input limit fails with
InsufficientLiquidity. Minting or
moving into a hotkey whose deposit belongs to another coldkey fails with
NonAssociatedColdKey.
Through a proxy, minting and moving need an Any or NonCritical proxy.
Setting a deposit's spender or daily spend cap and closing it also take a
NonTransfer proxy.
Deposits and API keys
Any account can be a deposit's hotkey, and it needs no registration or funds. A hotkey holds at most one deposit per subnet, owned by the coldkey that opened it, so create a fresh hotkey for each deposit. Requests signed with it are paid from the deposit, so never use a staking hotkey or a coldkey. A coldkey holds at most 64 deposits per subnet.
btcli gamma list
btcli gamma show --netuid 51 --hotkey API_KEYTo give someone gamma, open a deposit with their hotkey. The deposit stays yours: move the gamma back at any time.
btcli gamma move --netuid 51 --origin-hotkey THEIR_KEY --destination-hotkey API_KEY --amount-gamma allmove-gamma to a hotkey with no deposit opens one with
the origin's spender and daily spend cap. A move that empties the origin closes
it. A deposit spent to zero stays open with its terms, so it can be refilled,
until it is closed with close-gamma-deposit:
btcli gamma close --netuid 51 --hotkey API_KEYSpenders and daily spend caps
The spender stays the same if the subnet changes hands. Name another account
with set-gamma-deposit-spender and
--spender SPENDER, a service's spender with --service-hotkey SERVICE_HOTKEY,
or --default-spender for the spender of the subnet owner's service, otherwise
the subnet's current owner, or its lease's beneficiary:
btcli gamma set-spender --netuid 51 --hotkey API_KEY --service-hotkey SERVICE_HOTKEYA daily spend cap, set with
set-gamma-deposit-daily-spend-cap,
bounds what the spender can take. What it allows refills linearly at the cap
per 7200 blocks, up to the cap. A cap set where there was none starts full, and
a changed cap keeps what it allows now, up to the new cap, so ending a pause
refills from nothing. A cap of zero pauses the deposit, and --remove-cap
removes the cap.
While a deposit has a cap, a spender takes at most the highest cap plus its refill over any period. A deposit opened with a cap starts full.
btcli gamma set-cap --netuid 51 --hotkey API_KEY --daily-spend-cap-gamma 20A mint can name a new deposit's terms with --spender SPENDER or
--service-hotkey SERVICE_HOTKEY, and --daily-spend-cap-gamma 20, so the
deposit never opens on others. A deposit that already has other terms fails the
mint with
GammaDepositSpenderMismatch
or
GammaDepositDailySpendCapMismatch.
Spending
The spender spends many deposits in one spend-gamma
call, up to 512 entries of a hotkey, an amount and a reference:
btcli gamma spend --netuid 51 --spend API_KEY=0.25:0xREFERENCE --spend OTHER_KEY=1.5result = await client.execute(
bt.SpendGamma(
netuid=51,
spends=[{"hotkey_ss58": api_key, "amount_gamma": 0.25, "reference": reference}],
),
spender,
)Each entry spends its whole amount, and the spent gamma is destroyed. Entries
whose hotkey has no deposit, whose deposit names another spender, or whose
amount is zero or above the deposit's balance or what its daily spend cap
allows now, are skipped, and cost less as they write nothing.
spendable_gamma in gamma-deposit is what an
entry can spend now. Once the spend runs, result.data["spent"] lists each
entry that spent, with its hotkey_ss58, amount_gamma as an exact decimal
string, and reference, and result.data["skipped"] lists each entry that was
skipped, with the chain error that skipped it as reason, such as
InsufficientGammaBalance.
A reference is any 32 bytes, all zero when omitted. The chain repeats it in the
entry's GammaSpent or GammaSpendSkipped event and reads it nowhere else, so
an entry sent twice spends twice. By convention it is the service's own 32-byte id for the request
the entry pays for, returned with its response, so the customer can match each
spend to its own request.
Since the coldkey can change the spender or pause the deposit at any time, a
service spends ahead: it spends what it is about to serve, and serves what was
spent. The spender can hand this right to a GammaSpend proxy, which can
make no other call and spends with --proxy-for (proxy_for= in Python):
btcli proxy add --delegate BILLING_KEY --proxy-type GammaSpend -w SERVICE
btcli gamma spend --netuid 51 --spend API_KEY=0.25 -w BILLING_KEY --proxy-for SERVICEThe TAO/USD price
An oracle set by root feeds the TAO/USD price in gamma units, 10^9 per US
dollar, so 400 dollars per TAO is fed as 400000000000. The accepted price falls
to a lower feed at once and rises toward a higher one by at most 0.0066% (66
ppm) per block, about 2% per hour. A mint values TAO at the accepted price and
needs a feed at most 300 blocks (one hour) old; otherwise it fails with
TaoUsdPriceUnavailable. Setting
or removing the oracle clears the price, so no gamma can be minted until an
oracle feeds. Read it with tao-usd-price:
btcli query tao-usd-priceLimitations
- Gamma confers no claim on any party and cannot be redeemed. A subnet decides whether, and at what prices, it accepts its gamma.
- Dissolving or pruning a subnet destroys all of its gamma, and holders receive nothing.
- Spent gamma pays its spender nothing: the burned alpha's value accrues to the subnet's alpha holders.
- While a coldkey swap is announced, the coldkey's gamma calls are refused, but its spenders keep spending. A spender whose own swap is announced cannot spend.
- A coldkey swap adds the coldkey's deposits to the new coldkey's. It fails if the new coldkey would hold more than 64 on a subnet, and is refused when the two coldkeys hold more than 128 together.
- A spender's coldkey swap does not change any deposit's or service's spender.
After a subnet owner or lease beneficiary swaps its coldkey, the deposits and
the owner's service that name the old coldkey keep it. The owner republishes
its service, and a deposit's coldkey re-points it with
btcli gamma set-spender --default-spender. An owner whose service names a spender that never needs a swap, such as a multisig, needs neither. - The oracle is trusted: its accepted price can rise at most about 61% per day, until root replaces or removes it.