Prepare a fusion that makes a new card
const url = 'https://foxleague.ai/api/fusion/prepare';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"nonces":[1],"position_choice":1}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}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_choiceis 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.(codefusion_updating): no fusion can be made now (fusion_mint.pausedin/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_gatein/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.(codefusion_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 againand the messages that the chain cannot be read: nothing was signed.
Authorizations
Section titled “Authorizations ”Request Body required
Section titled “Request Body required ”The three cards to fuse and the position of the new card.
object
The NFT nonces of your three cards, in the order they are sent.
0, 1 or 2: the new card takes the position of this card of nonces.
Example generated
{ "nonces": [ 1 ], "position_choice": 1}Responses
Section titled “ Responses ”Success or a refusal: read success (the refusals are in the description).
object
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.
The answer. Present when success is true.
object
The fusion cost in FOXSY wei, as a decimal string. It is already in sc_call_data.
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.
The FOXSY token identifier.
The gas limit to sign the transaction with. Sign exactly this number: the call grows with its data.
The three cards, in the order they are sent.
The position choice the transaction carries.
The stats part of the card this transaction makes.
object
The average of the 7 stats, rounded down.
The new card’s position: GK, DEF, MID or FWD.
The new card’s rarity, one above the three cards’.
The 7 stats in order: speed, accuracy, defense, power, control, vision, stamina.
One of the 7 stats of the new card and the three cards’ values it is the average of.
object
This stat on each of the three cards, in the order of nonces, each in the range of its own rarity.
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.
The stat: speed, accuracy, defense, power, control, vision or stamina.
The value the new card gets.
The players contract the call data pays and calls. The transaction itself goes from your wallet to your own address.
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.
Why the request was refused, in plain words. Present when success is false.
true when the request did what it asked. false is a refusal: read error.
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.
Example
Session expired or invalidThe body does not match the request schema, for example a nonce that is not a number. The body is plain text.