Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ node_modules
tsconfig.tsbuildinfo
*.vitest-temp.json
**/.env
.npmrc
.npmrc
CLAUDE*.md
2 changes: 1 addition & 1 deletion examples/external-match/base-sepolia/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"start": "tsx index.ts"
},
"dependencies": {
"@renegade-fi/renegade-sdk": "latest",
"@renegade-fi/renegade-sdk": "workspace:*",
"viem": "latest"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion examples/external-match/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"start": "tsx index.ts"
},
"dependencies": {
"@renegade-fi/renegade-sdk": "latest",
"@renegade-fi/renegade-sdk": "workspace:*",
"viem": "latest"
},
"devDependencies": {
Expand Down
72 changes: 34 additions & 38 deletions examples/external-match/direct-malleable-match/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,68 +39,63 @@ if (!matchResponse) {
}

console.log("Received malleable external match response", {
gasSponsored: matchResponse.gas_sponsored,
gasSponsored: matchResponse.gas_sponsorship_info != null,
gasSponsorshipInfo: matchResponse.gas_sponsorship_info,
});

// --- Malleable Bundle Manipulation --- //

// Print bundle info
// Print bundle info (v2 uses input/output terminology)
console.log("\nBundle bounds:");
const [minBase, maxBase] = matchResponse.baseBounds();
const [minQuote, maxQuote] = matchResponse.quoteBounds();
console.log(`Base bounds: ${minBase} - ${maxBase}`);
console.log(`Quote bounds: ${minQuote} - ${maxQuote}`);
const [minInput, maxInput] = matchResponse.inputBounds();
const [minOutput, maxOutput] = matchResponse.outputBounds();
console.log(`Input bounds: ${minInput} - ${maxInput}`);
console.log(`Output bounds: ${minOutput} - ${maxOutput}`);

// Set a specific base amount on the bundle
// Set a specific input amount on the bundle
// This modifies the settlement transaction calldata to use the specified amount
const targetBaseAmount = minBase + (maxBase - minBase) / BigInt(2);
const receiveAmount = matchResponse.setBaseAmount(targetBaseAmount);
const targetInputAmount = minInput + (maxInput - minInput) / BigInt(2);
const receiveAmount = matchResponse.setInputAmount(targetInputAmount);
const sendAmount = matchResponse.sendAmount();

console.log(`\nSet base amount: ${targetBaseAmount}`);
console.log(`\nSet input amount: ${targetInputAmount}`);
console.log(`Send amount: ${sendAmount}`);
console.log(`Receive amount: ${receiveAmount}`);

// Alternatively, you can set a quote amount instead:
// const targetQuoteAmount = minQuote + (maxQuote - minQuote) / BigInt(2);
// matchResponse.setQuoteAmount(targetQuoteAmount);

const bundle = matchResponse.match_bundle;
const tx = bundle.settlement_tx;

// --- Allowance Check --- //

const isSell = bundle.match_result.direction === OrderSide.SELL;
const address = isSell
? (bundle.match_result.base_mint as `0x${string}`)
: (bundle.match_result.quote_mint as `0x${string}`);
// Use the send amount that was set via setBaseAmount (or max if not set)
// The input token is what we send; skip ERC20 approval for native ETH sells
const inputMint = bundle.match_result.input_mint as `0x${string}`;
const amount = sendAmount; // This is the amount that will actually be sent
const spender = tx.to as `0x${string}`;

console.log("\nChecking allowance...");

const allowance = await publicClient.readContract({
address,
abi: erc20Abi,
functionName: "allowance",
args: [owner, spender],
});
if (!matchResponse.isNativeEthSell()) {
console.log("\nChecking allowance...");

if (allowance < amount) {
console.log("Allowance is less than amount, approving...");
const approveTx = await walletClient.writeContract({
address,
const allowance = await publicClient.readContract({
address: inputMint,
abi: erc20Abi,
functionName: "approve",
args: [spender, amount],
functionName: "allowance",
args: [owner, spender],
});
console.log("Submitting approve transaction...");
await publicClient.waitForTransactionReceipt({
hash: approveTx,
});
console.log("Successfully submitted approve transaction", approveTx);

if (allowance < amount) {
console.log("Allowance is less than amount, approving...");
const approveTx = await walletClient.writeContract({
address: inputMint,
abi: erc20Abi,
functionName: "approve",
args: [spender, amount],
});
console.log("Submitting approve transaction...");
await publicClient.waitForTransactionReceipt({
hash: approveTx,
});
console.log("Successfully submitted approve transaction", approveTx);
}
}

// --- Submit Bundle --- //
Expand All @@ -110,6 +105,7 @@ console.log("\nSubmitting bundle...");
const hash = await walletClient.sendTransaction({
to: tx.to as `0x${string}`,
data: tx.data as `0x${string}`,
value: BigInt(tx.value ?? "0x0"),
type: "eip1559",
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"start": "tsx index.ts"
},
"dependencies": {
"@renegade-fi/renegade-sdk": "latest",
"@renegade-fi/renegade-sdk": "workspace:*",
"viem": "latest"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion examples/external-match/direct-match/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"start": "tsx index.ts"
},
"dependencies": {
"@renegade-fi/renegade-sdk": "latest",
"@renegade-fi/renegade-sdk": "workspace:*",
"viem": "latest"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion examples/external-match/exact-output/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"start": "tsx index.ts"
},
"dependencies": {
"@renegade-fi/renegade-sdk": "latest",
"@renegade-fi/renegade-sdk": "workspace:*",
"viem": "latest"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion examples/external-match/exchange-metadata/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"start": "tsx index.ts"
},
"dependencies": {
"@renegade-fi/renegade-sdk": "latest",
"@renegade-fi/renegade-sdk": "workspace:*",
"viem": "latest"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"start": "tsx index.ts"
},
"dependencies": {
"@renegade-fi/renegade-sdk": "latest",
"@renegade-fi/renegade-sdk": "workspace:*",
"viem": "latest"
},
"devDependencies": {
Expand Down
74 changes: 21 additions & 53 deletions examples/external-match/malleable/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
import type { MalleableExternalMatchResponse } from "@renegade-fi/node";
import type { MalleableExternalMatchResponse } from "@renegade-fi/renegade-sdk";

/**
* Set a random base amount on the bundle and print the results
* Set a random input amount on the bundle and print the results
* @param bundle The malleable match bundle
*/
export function setRandomBaseAmount(bundle: MalleableExternalMatchResponse) {
export function setRandomInputAmount(bundle: MalleableExternalMatchResponse) {
// Print bundle info
console.log("Bundle info:");
const [minBase, maxBase] = bundle.baseBounds();
console.log(`Base bounds: ${minBase} - ${maxBase}`);

// Pick a random base amount and see the send and receive amounts at that base amount
const dummyBaseAmount = randomInRange(minBase, maxBase);
const dummySendAmount = bundle.sendAmountAtBase(dummyBaseAmount);
const dummyReceiveAmount = bundle.receiveAmountAtBase(dummyBaseAmount);
console.log(`Hypothetical base amount: ${dummyBaseAmount}`);
console.log(`Hypothetical send amount: ${dummySendAmount}`);
console.log("\nBundle info:");
const [minInput, maxInput] = bundle.inputBounds();
const [minOutput, maxOutput] = bundle.outputBounds();
console.log(`Input bounds: ${minInput} - ${maxInput}`);
console.log(`Output bounds: ${minOutput} - ${maxOutput}`);

// Pick a hypothetical input amount and see the receive amount
const dummyInputAmount = randomInRange(minInput, maxInput);
const dummyReceiveAmount = bundle.receiveAmountAtInput(dummyInputAmount);
console.log(`Hypothetical input amount: ${dummyInputAmount}`);
console.log(`Hypothetical send amount: ${dummyInputAmount}`);
console.log(`Hypothetical receive amount: ${dummyReceiveAmount}`);

// Pick an actual base amount to swap with
const swappedBaseAmount = randomInRange(minBase, maxBase);
// Pick an actual input amount to swap with
const swappedInputAmount = randomInRange(minInput, maxInput);

// Setting the base amount will return the receive amount at the new base
// You can also call sendAmount and receiveAmount to get the amounts at the
// currently set base amount
bundle.setBaseAmount(swappedBaseAmount);
// Setting the input amount returns the receive amount at the new input
// You can also call sendAmount() and receiveAmount() to get the amounts
// at the currently set input amount
bundle.setInputAmount(swappedInputAmount);
const send = bundle.sendAmount();
const recv = bundle.receiveAmount();
console.log(`Swapped base amount: ${swappedBaseAmount}`);
console.log(`Swapped input amount: ${swappedInputAmount}`);
console.log(`Send amount: ${send}`);
console.log(`Receive amount: ${recv}`);
}
Expand All @@ -36,36 +37,3 @@ export function setRandomBaseAmount(bundle: MalleableExternalMatchResponse) {
function randomInRange(min: bigint, max: bigint): bigint {
return min + BigInt(Math.floor(Math.random() * (Number(max) - Number(min))));
}

/**
* Set a random quote amount on the bundle and print the results
* @param bundle The malleable match bundle
*/
// biome-ignore lint/correctness/noUnusedVariables: User can choose to use this function in the example
function setRandomQuoteAmount(bundle: MalleableExternalMatchResponse) {
// Print bundle info
console.log("Bundle info:");
const [minQuote, maxQuote] = bundle.quoteBounds();
console.log(`Quote bounds: ${minQuote} - ${maxQuote}`);

// Pick a random base amount and see the send and receive amounts at that base amount
const dummyQuoteAmount = randomInRange(minQuote, maxQuote);
const dummySendAmount = bundle.sendAmountAtQuote(dummyQuoteAmount);
const dummyReceiveAmount = bundle.receiveAmountAtQuote(dummyQuoteAmount);
console.log(`Hypothetical quote amount: ${dummyQuoteAmount}`);
console.log(`Hypothetical send amount: ${dummySendAmount}`);
console.log(`Hypothetical receive amount: ${dummyReceiveAmount}`);

// Pick an actual base amount to swap with
const swappedQuoteAmount = randomInRange(minQuote, maxQuote);

// Setting the quote amount will return the receive amount at the new quote
// You can also call sendAmount and receiveAmount to get the amounts at the
// currently set quote amount
bundle.setQuoteAmount(swappedQuoteAmount);
const send = bundle.sendAmount();
const recv = bundle.receiveAmount();
console.log(`Swapped quote amount: ${swappedQuoteAmount}`);
console.log(`Send amount: ${send}`);
console.log(`Receive amount: ${recv}`);
}
55 changes: 28 additions & 27 deletions examples/external-match/malleable/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ExternalMatchClient } from "@renegade-fi/node";
import { API_KEY, API_SECRET, chainId, walletClient } from "./env";
import { setRandomBaseAmount } from "./helpers";
import { ExternalMatchClient, OrderSide } from "@renegade-fi/renegade-sdk";
import { API_KEY, API_SECRET, walletClient } from "./env";
import { setRandomInputAmount } from "./helpers";

if (!API_KEY) {
throw new Error("API_KEY is not set");
Expand All @@ -10,50 +10,51 @@ if (!API_SECRET) {
throw new Error("API_SECRET is not set");
}

const client = ExternalMatchClient.new({
apiKey: API_KEY,
apiSecret: API_SECRET,
chainId,
});
const client = ExternalMatchClient.newArbitrumSepoliaClient(API_KEY, API_SECRET);

const WETH_ADDRESS = "0xc3414a7ef14aaaa9c4522dfc00a4e66e74e9c25a";
const USDC_ADDRESS = "0xdf8d259c04020562717557f2b5a3cf28e92707d1";
const quoteAmount = BigInt(2_000_000); // 2 USDC
const side = "buy";
const side = OrderSide.BUY;

const order = {
base: WETH_ADDRESS,
quote: USDC_ADDRESS,
base_mint: WETH_ADDRESS,
quote_mint: USDC_ADDRESS,
side,
quoteAmount,
quote_amount: quoteAmount,
} as const;

console.log("Fetching quote...");

const quote = await client.getQuote({
order,
});
const quote = await client.requestQuote(order);

console.log("Assmbling quote...");
if (!quote) {
console.error("No quote available, exiting...");
process.exit(1);
}

const bundle = await client.assembleMalleableQuote({
quote,
});
console.log("Assembling malleable quote...");

const bundle = await client.assembleMalleableQuote(quote);

if (!bundle) {
console.error("No bundle available, exiting...");
process.exit(1);
}

// Set a base amount on the bundle
// Alternatively, you can set a quote amount on the bundle - see
// `setRandomQuoteAmount` in `helpers.ts`
setRandomBaseAmount(bundle);
// Set a random input amount on the bundle
setRandomInputAmount(bundle);

const tx = bundle.match_bundle.settlement_tx;
const tx = bundle.settlementTx();

// --- Submit Bundle --- //

console.log("Submitting bundle...");
console.log("\nSubmitting bundle...");

const hash = await walletClient.sendTransaction({
to: tx.to,
data: tx.data,
to: tx.to as `0x${string}`,
data: tx.data as `0x${string}`,
value: BigInt(tx.value ?? "0x0"),
type: "eip1559",
});

Expand Down
2 changes: 1 addition & 1 deletion examples/external-match/malleable/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"start": "tsx index.ts"
},
"dependencies": {
"@renegade-fi/node": "latest",
"@renegade-fi/renegade-sdk": "workspace:*",
"viem": "latest"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"start": "tsx index.ts"
},
"dependencies": {
"@renegade-fi/renegade-sdk": "latest",
"@renegade-fi/renegade-sdk": "workspace:*",
"viem": "latest"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"start": "tsx index.ts"
},
"dependencies": {
"@renegade-fi/renegade-sdk": "latest",
"@renegade-fi/renegade-sdk": "workspace:*",
"viem": "latest"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion examples/external-match/order-book-depth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"start": "tsx index.ts"
},
"dependencies": {
"@renegade-fi/renegade-sdk": "latest",
"@renegade-fi/renegade-sdk": "workspace:*",
"viem": "latest"
},
"devDependencies": {
Expand Down
Loading
Loading