-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathswapUsingBtc.js
132 lines (122 loc) · 3.52 KB
/
swapUsingBtc.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import {
Account,
GlittrSDK,
electrumFetchNonGlittrUtxos,
txBuilder,
addFeeToTx,
} from "@glittr-sdk/sdk";
const NETWORK = "regtest";
const API_KEY = "your-api-key";
const WIF = "user-wif-key";
// Initialize the Glittr client and user account.
const client = new GlittrSDK({
network: NETWORK,
apiKey: API_KEY,
glittrApi: "https://devnet-core-api.glittr.fi",
electrumApi: "https://devnet-electrum.glittr.fi",
});
const userAccount = new Account({ wif: WIF, network: NETWORK });
const userAddress = userAccount.p2tr().address;
async function buyYesTokenWithBTC(
ammContract,
swapAmountBTC,
slippagePercentage
) {
// Get the current AMM state.
const contractState = await client.getContractState(
ammContract[0],
ammContract[1]
);
const assetKeys = Object.keys(contractState.collateralized.amounts);
const yesAssetKey = assetKeys.find((key) => key.includes("YES"));
const noAssetKey = assetKeys.find((key) => key.includes("NO"));
if (!yesAssetKey || !noAssetKey) {
throw new Error("YES or NO asset not found in AMM contract");
}
const inputTotal = parseInt(contractState.collateralized.amounts[noAssetKey]);
const outputTotal = parseInt(
contractState.collateralized.amounts[yesAssetKey]
);
const outputAmount = Math.floor(
outputTotal - (inputTotal * outputTotal) / (inputTotal + swapAmountBTC)
);
if (outputAmount <= 0) {
throw new Error("Calculated output amount is 0");
}
const minOutput = Math.floor(
outputAmount - (outputAmount * slippagePercentage) / 100
);
console.log(
`Swapping ${swapAmountBTC} BTC: calculated output = ${outputAmount} YES tokens, with minimum acceptable = ${minOutput}`
);
// Build the swap transaction.
const tx = {
contract_call: {
contract: ammContract,
call_type: {
swap: {
pointer: 1,
assert_values: { min_out_value: minOutput.toString() },
},
},
},
transfer: {
transfers: [
{
asset: ["BTC", "0"], // BTC asset
output: 2,
amount: swapAmountBTC.toString(),
},
],
},
};
// Define fee outputs.
const nonFeeOutputs = [
{ script: txBuilder.compile(tx), value: 0 }, // OP_RETURN output with tx message.
{ address: userAddress, value: 546 },
{ address: userAddress, value: 546 },
];
// Fetch UTXOs to fund the fee.
const utxos = await electrumFetchNonGlittrUtxos(
client.electrumApi,
API_KEY,
userAddress
);
const nonFeeInputs = []; // leaving empty so fee inputs are selected automatically
// Use addFeeToTx to get fee inputs and adjusted outputs.
const { inputs, outputs } = await addFeeToTx(
NETWORK,
userAddress,
utxos,
nonFeeInputs,
nonFeeOutputs
);
// Broadcast the raw transaction with the fee inputs.
const txid = await client.createAndBroadcastRawTx({
account: userAccount.p2tr(),
inputs,
outputs,
});
console.log(`Swap TXID: ${txid}`);
console.log("[+] Waiting for swap transaction to be mined...");
while (true) {
try {
const message = await client.getGlittrMessageByTxId(txid);
console.log("Swap mined:", JSON.stringify(message));
break;
} catch (error) {
await delay(1000);
}
}
}
// Example usage
const ammContract = [
/* AMM contract block and order */
];
const swapAmountBTC = 0.01; // Amount of BTC to swap
const slippagePercentage = 10; // 10% slippage tolerance
buyYesTokenWithBTC(ammContract, swapAmountBTC, slippagePercentage).catch(
(error) => {
console.error("Error:", error);
}
);