Crowdloan docs
Look up any call, event, or storage item with code examples. Runtime v472 · Block #9,197,056
Developer documentation for the Crowdloan pallet of the Subtensor blockchain, part of the Bittensor decentralized AI network. This page is designed for developers integrating with the chain: look up any call, event, or storage item, copy code examples in TypeScript, Python, or Rust, and filter by your role. For in-depth explanations, version history, and relationships between items, see the Reference section.
Crowdloan
Create a crowdloan that will raise funds up to a maximum cap and if successful,
Calls 10
Creates a new crowdloan campaign to raise funds for a project.
Parameters
| Name | Type | Format | Description |
|---|---|---|---|
deposit | Compact<TaoBalance> | TaoBalance | deposit: Balance in chain native currency (RAO for TAO; ÷10⁹) |
min_contribution | Compact<TaoBalance> | TaoBalance | min_contribution: Balance in chain native currency (RAO for TAO; ÷10⁹) |
cap | Compact<TaoBalance> | TaoBalance | cap: Balance in chain native currency (RAO for TAO; ÷10⁹) |
end | Compact<u32> | Integer | end: Block number |
call | Option | — | call (Option) |
target_address | Option | — | target_address: optional Account address (32 bytes, SS58-encoded) |
// ----------------------------------------------------------------------
// HEADS UP: 3 args below have a complex type with no usable default.
// Look for `undefined as any` and replace them with real values
// before running — the snippet compiles, but will fail at runtime as-is.
// ----------------------------------------------------------------------
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Build create call (typed, named args)
const deposit = undefined as any /* TaoBalance — replace with real value */;
const min_contribution = undefined as any /* TaoBalance — replace with real value */;
const cap = undefined as any /* TaoBalance — replace with real value */;
const end = 0;
const call = undefined;
const target_address = undefined;
const tx = api.tx.Crowdloan.create({
deposit,
min_contribution,
cap,
end,
call,
target_address,
});Contributes TAO to an active crowdloan campaign.
Parameters
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | Compact<u32> | Integer | crowdloan_id: Crowdloan identifier |
amount | Compact<TaoBalance> | TaoBalance | amount: Balance in chain native currency (RAO for TAO; ÷10⁹) |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Build contribute call (typed, named args)
const crowdloan_id = 0;
const amount = 1_000_000_000n;
const tx = api.tx.Crowdloan.contribute({
crowdloan_id,
amount,
});Withdraws your contribution from an active crowdloan.
Parameters
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | Compact<u32> | Integer | crowdloan_id: Crowdloan identifier |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Build withdraw call (typed, named args)
const crowdloan_id = 0;
const tx = api.tx.Crowdloan.withdraw({
crowdloan_id,
});Finalizes a successful crowdloan that reached its cap.
Parameters
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | Compact<u32> | Integer | crowdloan_id: Crowdloan identifier |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Build finalize call (typed, named args)
const crowdloan_id = 0;
const tx = api.tx.Crowdloan.finalize({
crowdloan_id,
});Refunds contributors of a failed crowdloan.
Parameters
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | Compact<u32> | Integer | crowdloan_id: Crowdloan identifier |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Build refund call (typed, named args)
const crowdloan_id = 0;
const tx = api.tx.Crowdloan.refund({
crowdloan_id,
});Dissolves a crowdloan after all contributors are refunded.
Parameters
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | Compact<u32> | Integer | crowdloan_id: Crowdloan identifier |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Build dissolve call (typed, named args)
const crowdloan_id = 0;
const tx = api.tx.Crowdloan.dissolve({
crowdloan_id,
});Updates the minimum contribution amount.
Parameters
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | Compact<u32> | Integer | crowdloan_id: Crowdloan identifier |
new_min_contribution | Compact<TaoBalance> | TaoBalance | new_min_contribution: Balance in chain native currency (RAO for TAO; ÷10⁹) |
// ----------------------------------------------------------------------
// HEADS UP: 1 arg below has a complex type with no usable default.
// Look for `undefined as any` and replace it with real value
// before running — the snippet compiles, but will fail at runtime as-is.
// ----------------------------------------------------------------------
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Build update_min_contribution call (typed, named args)
const crowdloan_id = 0;
const new_min_contribution = undefined as any /* TaoBalance — replace with real value */;
const tx = api.tx.Crowdloan.update_min_contribution({
crowdloan_id,
new_min_contribution,
});Updates the end block for a crowdloan.
Parameters
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | Compact<u32> | Integer | crowdloan_id: Crowdloan identifier |
new_end | Compact<u32> | Integer | new_end: Block number |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Build update_end call (typed, named args)
const crowdloan_id = 0;
const new_end = 0;
const tx = api.tx.Crowdloan.update_end({
crowdloan_id,
new_end,
});Updates the funding cap for a crowdloan.
Parameters
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | Compact<u32> | Integer | crowdloan_id: Crowdloan identifier |
new_cap | Compact<TaoBalance> | TaoBalance | new_cap: Balance in chain native currency (RAO for TAO; ÷10⁹) |
// ----------------------------------------------------------------------
// HEADS UP: 1 arg below has a complex type with no usable default.
// Look for `undefined as any` and replace it with real value
// before running — the snippet compiles, but will fail at runtime as-is.
// ----------------------------------------------------------------------
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Build update_cap call (typed, named args)
const crowdloan_id = 0;
const new_cap = undefined as any /* TaoBalance — replace with real value */;
const tx = api.tx.Crowdloan.update_cap({
crowdloan_id,
new_cap,
});Set or clear the maximum cumulative contribution allowed per contributor
Parameters
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | Compact<u32> | Integer | crowdloan_id: Crowdloan identifier |
new_max_contribution | Option | — | new_max_contribution: optional Balance in chain native currency (RAO for TAO; ÷10⁹) |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Build set_max_contribution call (typed, named args)
const crowdloan_id = 0;
const new_max_contribution = undefined;
const tx = api.tx.Crowdloan.set_max_contribution({
crowdloan_id,
new_max_contribution,
});Events 11
Emitted when a new crowdloan campaign is created.
When it fires
- Creator has sufficient balance
- Parameters are valid
Fields
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | u32 | Integer | Unique identifier for the crowdloan |
creator | AccountId | SS58 Address | Account that created the crowdloan |
end_block | u32 | Integer | Block number when campaign ends |
cap | TaoBalance | — | Maximum TAO to raise (RAO) |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Subscribe to Created events
client.finalizedBlock$.subscribe(async (block) => {
const events = await api.event.Crowdloan.Created.get(block.hash);
for (const evt of events) {
console.log("Created:", evt.payload);
}
});Emitted when TAO is contributed to a crowdloan.
When it fires
- Crowdloan is active
- Contributor has balance
- Meets minimum
Fields
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | u32 | Integer | Crowdloan identifier |
contributor | AccountId | SS58 Address | Account that contributed |
amount | TaoBalance | — | Amount contributed (RAO) |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Subscribe to Contributed events
client.finalizedBlock$.subscribe(async (block) => {
const events = await api.event.Crowdloan.Contributed.get(block.hash);
for (const evt of events) {
console.log("Contributed:", evt.payload);
}
});Emitted when a contribution is withdrawn from a crowdloan.
When it fires
- Crowdloan not finalized
- Contributor has contribution
Fields
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | u32 | Integer | Crowdloan identifier |
contributor | AccountId | SS58 Address | Account that withdrew |
amount | TaoBalance | — | Amount withdrawn (RAO) |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Subscribe to Withdrew events
client.finalizedBlock$.subscribe(async (block) => {
const events = await api.event.Crowdloan.Withdrew.get(block.hash);
for (const evt of events) {
console.log("Withdrew:", evt.payload);
}
});Emitted when some contributors have been refunded.
When it fires
- Crowdloan not finalized
- Has more contributors than limit
Fields
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | u32 | Integer | Crowdloan identifier |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Subscribe to PartiallyRefunded events
client.finalizedBlock$.subscribe(async (block) => {
const events = await api.event.Crowdloan.PartiallyRefunded.get(block.hash);
for (const evt of events) {
console.log("PartiallyRefunded:", evt.payload);
}
});Emitted when all contributors have been refunded.
When it fires
- Final batch of refunds
Fields
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | u32 | Integer | Crowdloan identifier |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Subscribe to AllRefunded events
client.finalizedBlock$.subscribe(async (block) => {
const events = await api.event.Crowdloan.AllRefunded.get(block.hash);
for (const evt of events) {
console.log("AllRefunded:", evt.payload);
}
});Emitted when a crowdloan successfully reaches its cap.
When it fires
- Crowdloan reached cap
- Creator finalized
Fields
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | u32 | Integer | Crowdloan identifier |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Subscribe to Finalized events
client.finalizedBlock$.subscribe(async (block) => {
const events = await api.event.Crowdloan.Finalized.get(block.hash);
for (const evt of events) {
console.log("Finalized:", evt.payload);
}
});Emitted when a crowdloan creator tears down a campaign that never finalized.
When it fires
- Caller is the crowdloan creator
- The crowdloan is not finalized
- Every contribution except the creator's own has been refunded, so raised equals the creator contribution
Fields
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | u32 | Integer | Crowdloan identifier |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Subscribe to Dissolved events
client.finalizedBlock$.subscribe(async (block) => {
const events = await api.event.Crowdloan.Dissolved.get(block.hash);
for (const evt of events) {
console.log("Dissolved:", evt.payload);
}
});Emitted when minimum contribution is updated.
When it fires
- Crowdloan not finalized
- Creator updated
Fields
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | u32 | Integer | Crowdloan identifier |
new_min_contribution | TaoBalance | — | New minimum (RAO) |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Subscribe to MinContributionUpdated events
client.finalizedBlock$.subscribe(async (block) => {
const events = await api.event.Crowdloan.MinContributionUpdated.get(block.hash);
for (const evt of events) {
console.log("MinContributionUpdated:", evt.payload);
}
});Emitted when end block is updated.
When it fires
- Crowdloan not finalized
- Creator updated
Fields
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | u32 | Integer | Crowdloan identifier |
new_end_block | u32 | Integer | New end block |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Subscribe to EndUpdated events
client.finalizedBlock$.subscribe(async (block) => {
const events = await api.event.Crowdloan.EndUpdated.get(block.hash);
for (const evt of events) {
console.log("EndUpdated:", evt.payload);
}
});Emitted when funding cap is updated.
When it fires
- Crowdloan not finalized
- Creator updated
Fields
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | u32 | Integer | Crowdloan identifier |
new_cap | TaoBalance | — | New cap (RAO) |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Subscribe to CapUpdated events
client.finalizedBlock$.subscribe(async (block) => {
const events = await api.event.Crowdloan.CapUpdated.get(block.hash);
for (const evt of events) {
console.log("CapUpdated:", evt.payload);
}
});The maximum contribution was updated.
When it fires
- Caller authorized to make changes
Fields
| Name | Type | Format | Description |
|---|---|---|---|
crowdloan_id | u32 | Integer | crowdloan_id: Crowdloan identifier |
new_max_contribution | Option | — | new_max_contribution: optional Balance in chain native currency (RAO for TAO; ÷10⁹) |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Subscribe to MaxContributionUpdated events
client.finalizedBlock$.subscribe(async (block) => {
const events = await api.event.Crowdloan.MaxContributionUpdated.get(block.hash);
for (const evt of events) {
console.log("MaxContributionUpdated:", evt.payload);
}
});Storage 6
Map of (crowdloan_id, contributor) to contribution amount.
TaoBalance Keys
| Name | Type | Format | Description |
|---|---|---|---|
key1 | u32 | Integer | — |
key2 | AccountId | SS58 Address | — |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Query Contributions storage
const key1 = 0;
const key2 = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY";
const result = await api.query.Crowdloan.Contributions.getValue(key1, key2);
console.log("Contributions:", result);Map of crowdloan IDs to their information.
CrowdloanInfo Keys
| Name | Type | Format | Description |
|---|---|---|---|
key1 | u32 | Integer | — |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Query Crowdloans storage
const key1 = 0;
const result = await api.query.Crowdloan.Crowdloans.getValue(key1);
console.log("Crowdloans:", result);Temporarily set during finalize for dispatched call to access.
u32 (Integer)import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Query CurrentCrowdloanId storage (no keys - plain value)
const result = await api.query.Crowdloan.CurrentCrowdloanId.getValue();
console.log("CurrentCrowdloanId:", result);Storage for migration run status.
bool (Boolean (true/false))Keys
| Name | Type | Format | Description |
|---|---|---|---|
key1 | BoundedVec | — | — |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Query HasMigrationRun storage
const key1 = new Uint8Array(0);
const result = await api.query.Crowdloan.HasMigrationRun.getValue(key1);
console.log("HasMigrationRun:", result);A map of crowdloan ids to their optional maximum cumulative contribution per contributor.
TaoBalance Keys
| Name | Type | Format | Description |
|---|---|---|---|
key1 | u32 | Integer | — |
import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Query MaxContributions storage
const key1 = 0;
const result = await api.query.Crowdloan.MaxContributions.getValue(key1);
console.log("MaxContributions:", result);The next incrementing crowdloan ID.
u32 (Integer)import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Query NextCrowdloanId storage (no keys - plain value)
const result = await api.query.Crowdloan.NextCrowdloanId.getValue();
console.log("NextCrowdloanId:", result);Constants 7
The absolute minimum contribution allowed.
TaoBalance"100000000"import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Query AbsoluteMinimumContribution constant
const value = await api.constants.Crowdloan.AbsoluteMinimumContribution();
console.log("AbsoluteMinimumContribution:", value);
// Balance: divide by 10^9 for TAO
const tao = value / 1_000_000_000n;Maximum number of contributors per crowdloan.
u32500import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Query MaxContributors constant
const value = await api.constants.Crowdloan.MaxContributors();
console.log("MaxContributors:", value);Maximum duration a crowdloan can run.
u32432000import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Query MaximumBlockDuration constant
const value = await api.constants.Crowdloan.MaximumBlockDuration();
console.log("MaximumBlockDuration:", value);Minimum duration a crowdloan must run.
u3250400import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Query MinimumBlockDuration constant
const value = await api.constants.Crowdloan.MinimumBlockDuration();
console.log("MinimumBlockDuration:", value);The minimum deposit required to create a crowdloan.
TaoBalance"10000000000"import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Query MinimumDeposit constant
const value = await api.constants.Crowdloan.MinimumDeposit();
console.log("MinimumDeposit:", value);
// Balance: divide by 10^9 for TAO
const tao = value / 1_000_000_000n;The pallet ID used to derive crowdloan account addresses.
PalletId0x62742f636c6f616eimport { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Query PalletId constant
const value = await api.constants.Crowdloan.PalletId();
console.log("PalletId:", value);Maximum contributors that can be refunded per call.
u3250import { createClient, Binary } from "polkadot-api";
import { getWsProvider } from "polkadot-api/ws";
import { sub } from "@polkadot-api/descriptors"; // generated by: npx papi add sub -w wss://entrypoint-finney.opentensor.ai:443
const client = createClient(getWsProvider("wss://entrypoint-finney.opentensor.ai:443"));
const api = client.getTypedApi(sub);
// Query RefundContributorsLimit constant
const value = await api.constants.Crowdloan.RefundContributorsLimit();
console.log("RefundContributorsLimit:", value);Errors 28
The initial deposit for creating this crowdloan is below the required minimum. The creator must put up a deposit that meets MinimumDeposit to prevent spam campaign creation.
Common Causes
- Deposit amount is less than the MinimumDeposit constant
- Not accounting for the full deposit requirement when creating a campaign
How to Fix
Check the MinimumDeposit constant for the required amount,Increase your deposit to at least meet the minimum,Ensure you have enough free balance to cover the deposit
The fundraising cap for this crowdloan is set lower than the required deposit amount. The cap represents the maximum total funds the campaign can raise and must exceed the initial deposit.
Common Causes
- Setting cap lower than or equal to the deposit amount
- Misunderstanding the relationship between cap and deposit
How to Fix
Set the cap to a value higher than the deposit amount,Review campaign parameters before submission
The minimum contribution threshold you set for this crowdloan is below the absolute floor. There is a network-wide AbsoluteMinimumContribution that all campaigns must respect.
Common Causes
- Setting min_contribution below AbsoluteMinimumContribution
- Trying to allow micro-contributions that are below the dust threshold
How to Fix
Set min_contribution to at least AbsoluteMinimumContribution,Check the constant for the current floor value
The end block specified for this crowdloan has already passed. Crowdloans must have a future end block when created.
Common Causes
- Using a block number that has already been finalized
- Calculating end block incorrectly relative to current block height
How to Fix
Query System.Number to get the current block height,Set the end block to a future block number,Add your desired duration to the current block number
The duration between the current block and the end block is shorter than the required minimum. Crowdloans must run for at least MinimumBlockDuration blocks.
Common Causes
- End block is too close to the current block
- Duration does not meet the MinimumBlockDuration requirement
How to Fix
Extend the end block further into the future,Check MinimumBlockDuration for the minimum allowed campaign length,Calculate: end_block >= current_block + MinimumBlockDuration
The duration between the current block and the end block exceeds the maximum allowed. Crowdloans cannot run longer than MaximumBlockDuration blocks.
Common Causes
- End block is set too far in the future
- Duration exceeds MaximumBlockDuration
How to Fix
Reduce the end block to bring the duration within limits,Check MaximumBlockDuration for the maximum allowed campaign length
Your account does not have enough free balance to cover the crowdloan deposit or contribution amount.
Common Causes
- Free balance is lower than the required deposit (for creators)
- Free balance is lower than the contribution amount (for contributors)
- Not accounting for existential deposit or transaction fees
How to Fix
Check your free balance via System.Account,Transfer more TAO to your account,Reduce the deposit or contribution amount,Account for transaction fees and existential deposit
An arithmetic overflow occurred during crowdloan calculation.
Common Causes
- Contribution would exceed maximum possible value
- Internal calculation overflow
How to Fix
Reduce contribution amount,Check for extremely large values,Report as bug if unexpected
The crowdloan ID you referenced does not exist. It may have never been created, or it was already dissolved.
Common Causes
- Typo in the crowdloan ID
- Crowdloan was already dissolved and removed
- Using an ID from a different network or test environment
How to Fix
Query Crowdloan.Crowdloans to list valid campaign IDs,Verify the crowdloan ID matches an active campaign,Check if the campaign was recently dissolved
This crowdloan has already reached its fundraising cap. No more contributions can be accepted.
Common Causes
- Campaign successfully raised its full target amount
- Your contribution would push the total above the cap
How to Fix
Check the crowdloan status to verify it is fully funded,Look for other active campaigns that are still accepting contributions,Wait for the campaign to finalize and potentially create a new one
The contribution period for this crowdloan has ended. The campaign is past its end block and no longer accepts new contributions.
Common Causes
- Trying to contribute after the crowdloan end block has passed
- Campaign expired while your transaction was pending
How to Fix
Check the crowdloan end block against the current block height,If you already contributed, you can request a refund after the period ends,Look for other active campaigns still accepting contributions
Your contribution amount is below the minimum set by the crowdloan creator. Each campaign defines its own minimum contribution threshold.
Common Causes
- Contribution amount below the campaign min_contribution parameter
- Sending a dust amount that does not meet the threshold
How to Fix
Query the crowdloan details to find the min_contribution value,Increase your contribution to at least meet the minimum,Check Crowdloan.Crowdloans for the campaign parameters
You are not the creator of this crowdloan and cannot perform this administrative action. Only the account that created the campaign can manage it.
Common Causes
- Trying to finalize, dissolve, or modify a campaign you did not create
- Using the wrong account to sign the transaction
How to Fix
Sign the transaction with the account that originally created the crowdloan,Query Crowdloan.Crowdloans to verify the campaign creator address
This crowdloan has already been finalized. Finalization is a one-time operation that distributes funds and cannot be repeated.
Common Causes
- Attempting to finalize a campaign that was already finalized
- Transaction submitted twice or by multiple parties
How to Fix
Check the crowdloan status to verify it has been finalized,No further action needed — the finalization already completed successfully
A crowdloan finalization is already in progress.
How to Fix
The crowdloan contribution period has not ended yet.
Common Causes
- Trying to refund before end block
- Campaign is still accepting contributions
How to Fix
Wait for the contribution period to end,Check the crowdloan end block,Refunds are only available after the end block
You have no recorded contribution to this crowdloan. You cannot withdraw or claim from a campaign you did not contribute to.
Common Causes
- Trying to withdraw from a campaign you never contributed to
- Already withdrew your contribution
- Using the wrong account (your contribution is under a different address)
How to Fix
Query Crowdloan.Contributions to verify your contribution status,Check that you are using the same account that made the contribution,If you already withdrew, no further action is needed
The crowdloan has not yet reached its fundraising cap. Finalization requires the campaign to be fully funded (or the contribution period to have ended, depending on configuration).
Common Causes
- Trying to finalize before the campaign has raised its target amount
- Campaign is still accepting contributions
How to Fix
Wait for the campaign to reach its cap before finalizing,Wait for the contribution period to end if the cap will not be reached,Check current raised amount against the cap in Crowdloan.Crowdloans
An arithmetic underflow occurred during crowdloan calculation.
Common Causes
- Trying to subtract more than available
- Internal calculation underflow
How to Fix
Check amounts are valid,Report as bug if unexpected
This crowdloan cannot be dissolved yet because it still has outstanding contributions. All contributors must be refunded before the campaign can be dissolved.
Common Causes
- Trying to dissolve before every non-creator contribution has been refunded
- A refund pass that stopped partway, leaving some contributors funded
How to Fix
Refund all remaining contributors first,Query Crowdloan.Contributions for this crowdloan id to find who is still funded,Compare the crowdloan raised total against your own contribution; dissolve is allowed only when they are equal
The deposit cannot be withdrawn from the crowdloan.
Common Causes
- Creator trying to withdraw initial deposit before it's allowed
- Deposit is locked until campaign concludes
- Only contributions over the deposit can be withdrawn
How to Fix
Wait for crowdloan to be dissolved,Creator deposit is returned on dissolve, not withdraw,Contributors can withdraw but creator deposit is special
This crowdloan has reached the maximum number of unique contributors allowed. No new contributors can join, though existing contributors may still increase their stake.
Common Causes
- Campaign has the maximum number of contributors
- High-demand campaign with limited contributor slots
How to Fix
Wait for a contributor slot to open up,Look for other active campaigns with available slots,If you already contributed, you can still increase your contribution amount
Exactly one of call or target address must be provided.
Common Causes
- Signing with the wrong key (e.g., hotkey instead of coldkey)
- Parameter value outside acceptable range
- Operation requires sudo or specific owner account
How to Fix
Check which key should sign: most staking ops need coldkey, weight ops need hotkey,Verify parameter ranges match the expected constraints,For owner-only calls, confirm you own the target resource
The contributor has already reached the maximum contribution.
How to Fix
The maximum contribution is too low.
How to Fix
The minimum contribution is too high.
How to Fix
The finalization call did not spend the full amount raised.