@dflow-protocol/swap-api-utils
v0.1.2
Published
Integration tools and helper functions for DFlow Swap API
Downloads
316
Readme
@dflow-protocol/swap-api-utils
Integration tools and helper functions for DFlow Swap API. This package provides utilities for sending, confirming, and monitoring Solana transactions and DFlow declarative swaps.
Installation
npm install @dflow-protocol/swap-api-utilsUsage
Submit and Monitor a DFlow Declarative Swap
import {
monitorOrder,
ORDER_STATUS,
type Intent,
type SubmitIntentResponse,
} from "@dflow-protocol/swap-api-utils";
import { Connection, Transaction } from "@solana/web3.js";
async function main() {
const connection = new Connection("YOUR_RPC_URL"); // Replace with your RPC URL. Use a paid RPC rather than api.mainnet-beta.solana.com.
const keypair = readKeypairFile("..."); // Replace to read your keypair file
const userPublicKey = keypair.publicKey;
const inputMint = "So11111111111111111111111111111111111111112"; // SOL
const outputMint = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; // USDC
const amount = "10000000"; // 0.01 SOL
const slippageBps = 1; // 0.01% slippage tolerance
const intentResponse = await fetch(
"https://quote-api.dflow.net/intent?"
+ `userPublicKey=${userPublicKey}`
+ `&inputMint=${inputMint}`
+ `&outputMint=${outputMint}`
+ `&amount=${amount}`
+ `&slippageBps=${slippageBps}`
);
if (!intentResponse.ok) {
const msg = await intentResponse.text();
throw new Error(`Failed to fetch quote: ${msg}`);
}
const intentData: Intent = await intentResponse.json();
if (!intentData.openTransaction) {
// This won't happen as long as we specify the userPublicKey in the GET /intent request, but we
// check anyway to satisfy the TypeScript type checker
console.log("Cannot execute swap for quote");
return;
}
console.log("Submitting order", intentData);
const openTransaction = Transaction.from(
Buffer.from(intentData.openTransaction, "base64"),
);
openTransaction.sign(keypair); // Sign the transaction with your keypair
const submitIntentResponse = await fetch(
"https://quote-api.dflow.net/submit-intent",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
quoteResponse: intentData,
signedOpenTransaction: openTransaction.serialize().toString("base64"),
}),
},
);
if (!submitIntentResponse.ok) {
const msg = await intentResponse.text();
throw new Error(`Failed to submit intent: ${msg}`);
}
const submitIntentData: SubmitIntentResponse = await submitIntentResponse.json();
console.log("Monitoring order");
const result = await monitorOrder({
connection,
intent: intentData,
signedOpenTransaction: openTransaction,
submitIntentResponse: submitIntentData,
});
switch (result.status) {
case ORDER_STATUS.CLOSED: {
if (result.fills.length > 0) {
// Order was filled and closed
const qtyIn = result.fills.reduce((acc, x) => acc + x.qtyIn, 0n);
const qtyOut = result.fills.reduce((acc, x) => acc + x.qtyOut, 0n);
console.log(`Order succeeded: sent ${qtyIn}, received ${qtyOut}`);
} else {
// Order was closed without any fills
console.log("Order failed");
}
break;
}
case ORDER_STATUS.PENDING_CLOSE: {
if (result.fills.length > 0) {
// Order was filled and is now closable
const qtyIn = result.fills.reduce((acc, x) => acc + x.qtyIn, 0n);
const qtyOut = result.fills.reduce((acc, x) => acc + x.qtyOut, 0n);
console.log(`Order succeeded: sent ${qtyIn}, received ${qtyOut}`);
} else {
// Order was not filled and is now closable
console.log("Order failed");
}
break;
}
case ORDER_STATUS.OPEN_EXPIRED: {
// Transaction to open the order expired
console.log("Transaction expired. Try again with a higher slippage tolerance.");
break;
}
case ORDER_STATUS.OPEN_FAILED: {
// Transaction to open the order was executed and failed
console.log("Order failed", result.transactionError);
break;
}
}
}Sending and Confirming Transactions
import { sendAndConfirmTransaction, TRANSACTION_STATUS } from "@dflow-protocol/swap-api-utils";
import { Connection, Transaction } from "@solana/web3.js";
async function executeTransaction() {
const readConnection = new Connection("YOUR_RPC_URL");
const writeConnection = new Connection("YOUR_RPC_URL");
const transaction = new Transaction();
// ... add instructions to transaction ...
// ... assign blockhash and fee payer ...
// ... sign transaction ...
const result = await sendAndConfirmTransaction({
readConnection,
writeConnections: [writeConnection],
transaction,
lastValidBlockHeight: 12345
});
if (result.status === TRANSACTION_STATUS.SUCCESS) {
console.log("Transaction confirmed");
} else if (result.status === TRANSACTION_STATUS.FAILED) {
console.log("Transaction failed", result.transactionError);
} else if (result.status === TRANSACTION_STATUS.EXPIRED) {
console.log("Transaction expired");
}
}