deBridge cross-chain bets
The deBridge API (opens in a new tab) allows to execute bets on Polygon originating from different blockchains, such as Arbitrum
.
This feature works only for Prematch Bets
in Supported Blockchains
(opens in a new tab)
First of all, you need to get a list of supported blockchains and tokens.
Get supported blockchains
type SupportedChainsResponse = {
chains: {
chainId: number
chainName: string
}[]
}
const response = await fetch('https://api.dln.trade/v1.0/supported-chains-info')
const { chains }: SupportedChainsResponse = await response.json()
Get supported tokens
You can pick one of supported blockchains from previous step and get supported tokens:
type SupportedTokensResponse = {
tokens: Record<string, {
address: string
symbol: string,
decimals: number,
name: string,
logoURI: string,
tags: Array<string>
}>
}
const chainId = 42161 // Arbitrum for example
const response = await fetch(`https://api.dln.trade/v1.0/token-list?chainId=${chainId}`)
const { tokens }: SupportedTokensResponse = await response.json()
const supportedTokens = Object.values(tokens) // list of supported tokens
Create transaction and get quotes
Now you need to generate your referral code for deBridge. Go to deBridge (opens in a new tab) website and click the REFER
button after that on GENERATE
. Or you can go directly to https://app.debridge.finance/statistic/YOUR_WALLET_ADDRESS/referral
.
For more information about bet transaction data check Place a Bet section.
import { encodeFunctionData } from 'viem'
type DeBridgeCreateTxResponse = {
orderId: Hex
estimation: {
srcChainTokenIn: {
address: Address
name: string
symbol: string
decimals: number
amount: string
approximateOperatingExpense: string
mutatedWithOperatingExpense: boolean
},
srcChainTokenOut: {
address: Address
name: string
symbol: string
decimals: number
amount: string
maxRefundAmount: string
}
dstChainTokenOut: {
address: Address
name: string
symbol: string
decimals: number
amount: string
recommendedAmount: string
withoutAdditionalTakerRewardsAmount: string
maxTheoreticalAmount: string
},
recommendedSlippage: number
costsDetails: [ string ]
}
tx: {
to: Address
data: Hex
value: bigint
}
order: {
approximateFulfillmentDelay: number
},
prependedOperatingExpenseCost: string
fixFee: string
userPoints: number
integratorPoints: number
}
const fromChainId = 42161 // Arbitrum for example
const fromTokenAddress = '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9' // USDT
const referralCode = '' // your deBridge referral code
const selections = [{...}]
const rawAmount = '...'
const rawDeadline = '...'
const affiliate = '...'
const minOdds = '...'
const betData = 0x...
const params = new URLSearchParams({
dstChainId: 137, // Polygon
srcChainOrderAuthorityAddress: bettorAddress as string,
prependOperatingExpenses: 'false',
srcChainId: String(fromChainId),
srcChainTokenIn: fromTokenAddress,
srcChainTokenInAmount: 'auto',
dstChainTokenOut: '0xc2132d05d31c914a87c6611c10748aeb04b58e8f', // USDT in Polygon
dstChainTokenOutAmount: String(rawAmount),
dstChainTokenOutRecipient: bettorAddress as string,
dstChainOrderAuthorityAddress: bettorAddress as string,
externalCall: JSON.stringify({
version: 'evm_1',
fields: {
to: lpAddress,
data: encodeFunctionData({
abi: lpAbi,
functionName: 'betFor',
args: [
bettorAddress,
coreAddress,
rawAmount,
rawDeadline,
{
affiliate,
minOdds,
data: betData,
},
],
}),
},
}),
referralCode: String(referralCode), // your referral code
})
const deBridgeCreateTxResponse = await fetch(`https://api.dln.trade/v1.0/dln/order/create-tx?${params}`)
const {
orderId, // deBridge order id
estimation, // information about gas expense, etc.
tx, // transaction data
fixFee // deBridge fixed fee in native tokens
}: DeBridgeCreateTxResponse = await deBridgeCreateTxResponse.json()
It's necessary to use the betFor
function rather than the bet
function to ensure that the bettor can redeem their bet.
Send transaction and order checking
Don't forget allowance checks and tokens spending approve:
import { useWriteContract, useReadContract } from 'wagmi'
import { erc20Abi, maxUint256, zeroAddress } from 'viem'
const isNative = estimation?.srcChainTokenIn?.address === zeroAddress
const allowanceTx = useReadContract({
chainId: fromChainId,
address: estimation?.srcChainTokenIn.address,
abi: erc20Abi,
functionName: 'allowance',
args: [
bettorAddress!,
tx?.to as Address,
],
query: {
enabled: !isNative && Boolean(bettorAddress),
refetchOnWindowFocus: false,
},
})
const isApproveRequired = Boolean(
allowanceTx.data !== undefined
&& allowanceTx.data < BigInt(estimation?.srcChainTokenIn?.amount || 0)
)
const approveTx = useWriteContract()
approveTx.writeContract({
address: estimation?.srcChainTokenIn.address!,
abi: erc20Abi,
chainId: fromChainId,
functionName: 'approve',
args: [
tx?.to as Address,
maxUint256,
],
})
Send transaction from another step and checking order fulfilment in interval:
enum DeBridgeOrderStatus {
None = 'None',
Created = 'Created',
Fulfilled = 'Fulfilled',
SentUnlock = 'SentUnlock',
OrderCancelled = 'OrderCancelled',
SentOrderCancel = 'SentOrderCancel',
ClaimedUnlock = 'ClaimedUnlock',
ClaimedOrderCancel = 'ClaimedOrderCancel',
}
enum DeBridgeExternalCallStatus {
NoExtCall = 'NoExtCall',
AwaitingOrderFulfillment = 'AwaitingOrderFulfillment',
AwaitingExecution = 'AwaitingExecution',
Executing = 'Executing',
Completed = 'Completed',
Failed = 'Failed',
Cancelled = 'Cancelled',
}
type DeBridgeOrderStatusResponse = {
orderId: Hex
status: DeBridgeOrderStatus
externalCallState: DeBridgeExternalCallStatus
}
type DeBridgeOrderTxResponse = {
fulfilledDstEventMetadata: {
transactionHash: {
stringValue: string
}
}
}
await sendTransaction(tx) // send transaction
/*
txHash - bet transaction hash in Polygon
*/
const txHash = await new Promise<Hex>((res, rej) => {
const interval = setInterval(async () => {
const orderResponse = await fetch(`https://api.dln.trade/v1.0/dln/order/${orderId}`)
const order: DeBridgeOrderStatusResponse = await orderResponse.json()
const {
status: orderStatus,
externalCallState: betPlacingStatus,
} = order
const isBetPlaced = betPlacingStatus === DeBridgeExternalCallStatus.Completed
const isOrderFulfilled = isBetPlaced || orderStatus === DeBridgeOrderStatus.Fulfilled || orderStatus === DeBridgeOrderStatus.ClaimedUnlock
if (isOrderFulfilled) {
clearInterval(interval)
const orderTxResponse = await fetch(`https://stats-api.dln.trade/api/orders/${orderId}`)
const { fulfilledDstEventMetadata }: DeBridgeOrderTxResponse = await orderTxResponse.json()
res(fulfilledDstEventMetadata?.transactionHash?.stringValue as Hex)
}
let error = ''
if (betPlacingStatus === DeBridgeExternalCallStatus.Cancelled) {
error = DeBridgeExternalCallStatus.Cancelled
}
if (betPlacingStatus === DeBridgeExternalCallStatus.Failed) {
error = DeBridgeExternalCallStatus.Failed
}
if (orderStatus === DeBridgeOrderStatus.SentOrderCancel) {
error = DeBridgeOrderStatus.SentOrderCancel
}
if (orderStatus === DeBridgeOrderStatus.OrderCancelled) {
error = DeBridgeOrderStatus.OrderCancelled
}
if (error) {
clearInterval(interval)
rej(error)
}
}, 5000)
})
More api information you can find in deBridge Swagger (opens in a new tab)