Velora Delta is an intent-based protocol that enables a Velora user to make gasless swaps where multiple agents compete to execute the trade at the best price possible. This way the user doesn't need to make a transaction themselves but only to sign a Delta Order. The easiest way to make use of the Delta Order is to use the SDK following these steps:
const account = userAddress;
const deltaSDK = constructSimpleSDK(
{chainId: 1, axios},
{
ethersProviderOrSigner: provider, // JsonRpcProvider
EthersContract: ethers.Contract,
account,
});
// for usage with different web3 provider libraries refer to the main [README](./README.md)const DAI_TOKEN = '0x6b175474e89094c44da98b954eedeac495271d0f';
const USDC_TOKEN = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
const amount = '1000000000000'; // in wei
const deltaPrice = await deltaSDK.getDeltaPrice({
srcToken: DAI_TOKEN,
destToken: USDC_TOKEN,
amount,
userAddress: account,
srcDecimals: 18,
destDecimals: 6,
// partner: "..." // if available
});const tx = await deltaSDK.approveTokenForDelta(amount, DAI_TOKEN);
await tx.wait();Alternatively sign Permit (DAI or Permit1) or Permit2 TransferFrom with DeltaContract as the verifyingContract
const DeltaContract = await deltaSDK.getDeltaContract();
// values depend on the Permit type and the srcToken
const signature = await signer._signTypedData(domain, types, message);See more on accepted Permit variants in Velora documentation
// calculate acceptable destAmount
const slippagePercent = 0.5;
const destAmountAfterSlippage = (
+deltaPrice.destAmount *
(1 - slippagePercent / 100)
).toString(10);
const deltaAuction = await deltaSDK.submitDeltaOrder({
deltaPrice,
owner: account,
// beneficiary: anotherAccount, // if need to send destToken to another account
// permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract
srcToken: DAI_TOKEN,
destToken: USDC_TOKEN,
srcAmount: amount,
destAmount: destAmountAfterSlippage, // minimum acceptable destAmount
});// poll if necessary
function isExecutedDeltaAuction(
auction: Omit<DeltaAuction, 'signature'>,
waitForCrosschain = true // only consider executed when destChain work is done
) {
if (auction.status !== 'EXECUTED') return false;
// crosschain Order is executed on destChain if bridgeStatus is filled
if (waitForCrosschain && auction.order.bridge.destinationChainId !== 0) {
return auction.bridgeStatus === 'filled';
}
return true;
}
function fetchOrderPeriodically(auctionId: string) {
const intervalId = setInterval(async () => {
const auction = await simpleSDK.delta.getDeltaOrderById(auctionId);
console.log('checks: ', auction); // Handle or log the fetched auction as needed
if (isExecutedDeltaAuction(auction)) {
clearInterval(intervalId); // Stop interval if completed
console.log('Order completed');
}
}, 3000);
console.log('Order Pending');
// Return intervalId to enable clearing the interval if needed externally
return intervalId;
}
function startStatusCheck(auctionId: string) {
const intervalId = fetchOrderPeriodically(auctionId);
setTimeout(() => clearInterval(intervalId), 60000 * 5); // Stop after 5 minutes
}
startStatusCheck(deltaAuction.id);A more detailed example of Delta Order usage can be found in examples/delta
In case you want to perform a crosschain swap, the process is a little more involved.
const SRC_CHAIN_ID = 1 // Ethereum
const DEST_CHAIN_ID = 10; // Optimism
const account = userAddress;
const deltaSDK = constructSimpleSDK(
{chainId: SRC_CHAIN_ID, axios},
{
ethersProviderOrSigner: provider, // JsonRpcProvider
EthersContract: ethers.Contract,
account,
});
// for usage with different web3 provider libraries refer to the main [README](./README.md)A limited list of tokens are available in Across, the service facilitating crosschain bridging
const bridgeInfo = await deltaSDK.getBridgeInfo();
const tokensAvailableForBridging = bridgeInfo[SRC_CHAIN_ID]?.[DEST_CHAIN_ID]const DAI_TOKEN = '0x6b175474e89094c44da98b954eedeac495271d0f';
const USDC_TOKEN_ON_DEST_CHAIN = '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85'; // available for bridging on Optimism
const amount = '1000000000000'; // in wei
const deltaPrice = await deltaSDK.getDeltaPrice({
srcToken: DAI_TOKEN,
destToken: USDC_TOKEN_ON_DEST_CHAIN,
destChainId: DEST_CHAIN_ID, // required to get deltaPrice for a Crosschain Order
amount,
userAddress: account,
srcDecimals: 18,
destDecimals: 6,
// partner: "..." // if available
});const tx = await deltaSDK.approveTokenForDelta(amount, DAI_TOKEN);
await tx.wait();Alternatively sign Permit (DAI or Permit1) or Permit2 TransferFrom with DeltaContract as the verifyingContract
const DeltaContract = await deltaSDK.getDeltaContract();
// values depend on the Permit type and the srcToken
const signature = await signer._signTypedData(domain, types, message);See more on accepted Permit variants in Velora documentation
// calculate acceptable destAmount
const slippagePercent = 0.5;
const destAmountAfterSlippage = (
+deltaPrice.destAmount *
(1 - slippagePercent / 100)
).toString(10);
const deltaAuction = await deltaSDK.submitDeltaOrder({
deltaPrice,
owner: account,
// permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract
srcToken: DAI_TOKEN,
destToken: USDC_TOKEN_ON_DEST_CHAIN,
srcAmount: amount,
destAmount: destAmountAfterSlippage, // minimum acceptable destAmount
destChainId: DEST_CHAIN_ID, // required to construct a Crosschain Order
beneficiary: anotherAccount, // if need to send destToken to another account on destChain
beneficiaryType: 'EOA', // whether the beneficiary on destChain is a smart contract
// bridge, // user-constructed Bridge object for Crosschain Orders
});To construct a Crosschain Delta Order it is required to either:
- provide both
beneficiaryaddress andbeneficiaryTypevalue, so that theOrder.bridgecan be constructed automatically by the SDK. - construct Bridge object. Refer to documentation for how to do that.
This is necessary because Across, the service facilitating crosschain bridging, has special logic when it comes to transferring ETH and WETH.
// poll if necessary
function isExecutedDeltaAuction(
auction: Omit<DeltaAuction, 'signature'>,
waitForCrosschain = true // only consider executed when destChain work is done
) {
if (auction.status !== 'EXECUTED') return false;
// crosschain Order is executed on destChain if bridgeStatus is filled
if (waitForCrosschain && auction.order.bridge.destinationChainId !== 0) {
return auction.bridgeStatus === 'filled';
}
return true;
}
function fetchOrderPeriodically(auctionId: string) {
const intervalId = setInterval(async () => {
const auction = await simpleSDK.delta.getDeltaOrderById(auctionId);
console.log('checks: ', auction); // Handle or log the fetched auction as needed
if (isExecutedDeltaAuction(auction)) {
clearInterval(intervalId); // Stop interval if completed
console.log('Order completed');
}
}, 3000);
console.log('Order Pending');
// Return intervalId to enable clearing the interval if needed externally
return intervalId;
}
function startStatusCheck(auctionId: string) {
const intervalId = fetchOrderPeriodically(auctionId);
setTimeout(() => clearInterval(intervalId), 60000 * 5); // Stop after 5 minutes
}
startStatusCheck(deltaAuction.id);