Create B3MO Quests from Contract
This guide shows how to create a B3MO Quest directly through the B3TRChallenges contract, without using the VeBetterDAO platform UI.
The walkthrough creates a Sponsored Public Split Win quest:
the creator funds the full prize pool
anyone can join while the quest is pending
the first
numWinnersparticipants that reachthresholdactions can claim a fixed prize
In the contracts, B3MO Quests are still named "challenges". You will see names such as B3TRChallenges, createChallenge, and challengeId in the ABI.
Requirements
You need:
B3TR in the creator wallet
VTHO in the creator wallet to pay gas
the
B3TR,B3TRChallenges, andXAllocationVotingcontract addresses for your networka future allocation round for
startRoundoptional X2Earn app IDs if you want to count actions only from specific apps
Install the packages:
yarn add @vechain/sdk-core @vechain/sdk-network ethersContract Addresses
Testnet
https://testnet.vechain.org
0x3d920eab29134c23c4477686749608391a635587
0x4a6bc52a7eecac26a13e284b75266c0c40cbde91
0x8770a4659e42b7b4d7ac7fcaa27ef21b209372de
Mainnet
https://mainnet.vechain.org
0x5ef79995FE8a89e0812330E4378eB2660ceDe699
0x92a98f23ca4f9703781cf56088b76a1482667166
0x89A00Bb0947a30FF95BEeF77a66AEdE3842Fe5B7
Flow
Create a Sponsored Public Split Win Quest
Set the environment variables:
Then run:
The transaction has two clauses:
B3TR.approve(B3TRChallenges, stakeAmount)B3TRChallenges.createChallenge(params)
If the second clause reverts, the whole transaction reverts and the approval is not applied.
Parameters
kind
1 (Sponsored)
visibility
0 (Public)
challengeType
1 (SplitWin)
stakeAmount
Total B3TR prize pool, in wei
startRound
A future allocation round. Use currentRoundId() + 1 for the next round
endRound
Last round where actions count
threshold
Minimum action count required to claim a Split Win slot
numWinners
Number of prize slots
appIds
Empty array for all apps, or selected X2Earn app IDs
invitees
Empty array for public quests
title
Max 120 bytes
description
Max 500 bytes
imageURI
Optional, max 512 bytes
metadataURI
Optional, max 512 bytes
For Split Win, stakeAmount / numWinners is fixed when the quest is created. The contract requires at least 1 B3TR per winner.
Valid Quest Combinations
Sponsored
Public
SplitWin
threshold > 0, numWinners > 0, no invitees required
Sponsored
Private
MaxActions
threshold = 0, numWinners = 0, invitees optional
Sponsored
Private
SplitWin
threshold > 0, numWinners > 0, invitees optional
Stake
Private
MaxActions
threshold = 0, numWinners = 0, participants must approve and stake when joining
Public Stake quests, public MaxActions quests, and Stake SplitWin quests are invalid.
Lifecycle
Pending: users can join. The creator can cancel beforestartRound.Active: the quest has started and actions are counted through VeBetterPassport.Completed: rewards or refunds can be claimed.Cancelled: creator cancelled before the quest started.Invalid: the quest did not meet its activation rules.
Split Win quests do not use completeChallenge. Winners call claimSplitWinPrize while the quest is active. After endRound, the creator can call claimCreatorSplitWinRefund to reclaim unclaimed slots.
MaxActions quests are different: once the quest has ended, a participant or creator calls completeChallenge, then winners call claimChallengePayout.
Common Errors
InvalidAmount
stakeAmount is zero
BetAmountBelowMinimum
stakeAmount is below minBetAmount()
InvalidStartRound
startRound is not in the future
InvalidEndRound
endRound is before startRound
InvalidChallengeTypeForCombo
The selected kind, visibility, and type combination is not allowed
InvalidTypeConfiguration
threshold or numWinners does not match the selected type
InsufficientPrizePerWinner
Split Win prize per winner is below 1 B3TR
ChallengeUnknownApp
One of the selected appIds does not exist in X2EarnApps
MaxChallengeDurationExceeded
The round range is longer than maxChallengeDuration()
MaxSelectedAppsExceeded
Too many selected app IDs
Use maxChallengeDuration(), maxSelectedApps(), maxParticipants(), and minBetAmount() on B3TRChallenges to read the current limits before building your form or script.
Last updated
Was this helpful?