Skip to content

Prepare a fusion that makes a new card

POST
/api/fusion/prepare
curl --request POST \
--url https://foxleague.ai/api/fusion/prepare \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "nonces": [ 1 ], "position_choice": 1 }'

From the players contract’s fusion live time (fusion_mint.live in /api/config) a fusion makes a brand new card of the next rarity. This builds the transaction for three of your cards of one rarity and answers the stats part of the card it makes, exactly as the contract will make it: its position, rarity, OVR and 7 stats. The card also gets a new face, a generated name, the face’s country and a random shirt (1 to 99), level 1 and condition 100. The face, name, country and shirt are a surprise: they are not in preview and show once the card is minted (GET /api/players/nonce/{nonce}, the fusion history). Each of its 7 stats is the average of that stat over the three cards translated to the new rarity’s range (the three values added up, times the new cap, divided by 3 times the old cap, rounded down), then raised to the stat floor of the new rarity when lower. A stat reaches the new cap only when all three cards hold it at their cap, so it can be lower than the best of the three cards’ own values. preview.stats gives each stat with the three cards’ values.

Sign it as a transaction from your wallet to your own address, with sc_call_data as data, value 0 and exactly gas_limit. The signature in it is valid until expiry, more than 5 minutes after the call (10 minutes for a new signature): prepare again right before you sign. A call for the same position and rarity keeps the same new card, so preparing again re-rolls nothing. No sync is needed first. When it is final, send its hash to POST /api/fusion/confirm.

Who: a signed-in player with a team.

Refusals:

  • A fusion takes 3 different cards.
  • Choose the position of one of the 3 cards.: position_choice is not 0, 1 or 2.
  • Fusion does not mint new cards yet. Until then a fusion works as before.: before the live time.
  • Fusion is being updated. Nothing was signed. Try again later. (code fusion_updating): no fusion can be made now (fusion_mint.paused in /api/config); no face is held.
  • One of these cards is not in your squad. Refresh your team and choose again.
  • the rules of a fusion, each naming the card: not the same rarity, a Legendary, listed on the marketplace, injured, suspended, your wallet’s fusion cooldown, a card’s own fusion cooldown, too few competitive matches (rarity_match_gate in /api/config).
  • Not in your wallet on chain right now: <cards>. A listed card stays with the marketplace until the listing ends.: a card is not in your wallet (listed, sent or still arriving).
  • No new faces for <position> right now. Choose the position of another card or try again later.
  • Fusion is paused for a security check. Nothing was signed. Please try again later.
  • You are preparing fusions too quickly. Wait a moment and try again. Nothing was signed. (code fusion_prepare_pace): a new signature at most every 2 seconds per wallet; a call for exactly the payload already signed, with more than 5 minutes left, answers that signature again.
  • The new card could not be held. Nothing was signed. Please try again.
  • Signing service unavailable, try again and the messages that the chain cannot be read: nothing was signed.
Media type application/json

The three cards to fuse and the position of the new card.

object
nonces
required

The NFT nonces of your three cards, in the order they are sent.

Array<integer>
position_choice
required

0, 1 or 2: the new card takes the position of this card of nonces.

integer format: int32
Example generated
{
"nonces": [
1
],
"position_choice": 1
}

Success or a refusal: read success (the refusals are in the description).

Media type application/json
object
code

A machine-readable reason next to error, set only where the caller must act differently. tx_pending: the payment was not refused but could not be verified yet; keep the transaction hash and confirm again with the same hash, never pay twice.

string | null
data

The answer. Present when success is true.

object
cost_raw
required

The fusion cost in FOXSY wei, as a decimal string. It is already in sc_call_data.

string
expiry
required

The signature is accepted until this block time (UNIX seconds): 10 minutes after the call for a new signature, more than 5 minutes after it when a signature is answered again.

integer format: int64
foxsy_token_id
required

The FOXSY token identifier.

string
gas_limit
required

The gas limit to sign the transaction with. Sign exactly this number: the call grows with its data.

integer format: int64
nonces
required

The three cards, in the order they are sent.

Array<integer>
position_choice
required

The position choice the transaction carries.

integer format: int32
preview
required

The stats part of the card this transaction makes.

object
ovr
required

The average of the 7 stats, rounded down.

integer format: int32
position
required

The new card’s position: GK, DEF, MID or FWD.

string
rarity
required

The new card’s rarity, one above the three cards’.

string
stats
required

The 7 stats in order: speed, accuracy, defense, power, control, vision, stamina.

Array<object>

One of the 7 stats of the new card and the three cards’ values it is the average of.

object
input_values
required

This stat on each of the three cards, in the order of nonces, each in the range of its own rarity.

Array<integer>
scaled_value
required

The average of the three values translated to the new rarity’s range: their sum times the new cap, divided by 3 times the old cap, rounded down. Below value when a floor of the new rarity raised it.

integer format: int32
stat
required

The stat: speed, accuracy, defense, power, control, vision or stamina.

string
value
required

The value the new card gets.

integer format: int32
receiver
required

The players contract the call data pays and calls. The transaction itself goes from your wallet to your own address.

string
sc_call_data
required

The transaction data to sign, as text: the FOXSY cost and the three cards to the players contract with the fusionMint call and its signature.

string
error

Why the request was refused, in plain words. Present when success is false.

string | null
success
required

true when the request did what it asked. false is a refusal: read error.

boolean
Example
{
"success": true,
"data": {
"sc_call_data": "MultiESDTNFTTransfer@000000000000000005004f8a1c27b6d3e0951a2c8f7e6d4b3a2918c7f6e5d4c3@04@464f5853592d356435663365@00@056bc75e2d63100000@46584c502d366632386535@0dad@01@46584c502d366632386535@0e01@01@46584c502d366632386535@0e3c@01@667573696f6e4d696e74@01@6a7c75fa@7c1e...@0000000e...@0dad@...@0e01@...@0e3c@...",
"receiver": "erd1qqqqqqqqqqqqqpgqfl593rtmy3p9s9wys8aq463gz082srtvnndjut3kps",
"gas_limit": 33528500,
"expiry": 1795356600,
"cost_raw": "100000000000000000000",
"foxsy_token_id": "FOXSY-5d5f3e",
"nonces": [
3501,
3585,
3644
],
"position_choice": 1,
"preview": {
"position": "DEF",
"rarity": "Uncommon",
"stats": [
{
"stat": "speed",
"value": 30,
"input_values": [
15,
17,
18
],
"scaled_value": 30
},
{
"stat": "accuracy",
"value": 26,
"input_values": [
12,
14,
17
],
"scaled_value": 26
},
{
"stat": "defense",
"value": 28,
"input_values": [
18,
16,
12
],
"scaled_value": 28
},
{
"stat": "power",
"value": 25,
"input_values": [
13,
15,
14
],
"scaled_value": 25
},
{
"stat": "control",
"value": 27,
"input_values": [
14,
18,
13
],
"scaled_value": 27
},
{
"stat": "vision",
"value": 25,
"input_values": [
16,
12,
14
],
"scaled_value": 25
},
{
"stat": "stamina",
"value": 28,
"input_values": [
17,
13,
16
],
"scaled_value": 28
}
],
"ovr": 27
}
}
}

No valid session. The body is plain text: Missing Authorization header, Invalid Authorization format, Invalid session token or Session expired or invalid. Sign in again.

Media type text/plain
string
Example
Session expired or invalid

The body does not match the request schema, for example a nonce that is not a number. The body is plain text.