Skip to content

Commit

Permalink
feat: transaction manager update callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasDeco committed May 30, 2024
1 parent f4ef06b commit 323feba
Show file tree
Hide file tree
Showing 7 changed files with 379 additions and 102 deletions.
28 changes: 20 additions & 8 deletions lib/client/rpc/market-clients/ammMarkets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,17 @@ export class FutarchyAmmMarketsRPCClient implements FutarchyAmmMarketsClient {
this.rpcProvider.publicKey
);
const tx = await ix.transaction();
return this.transactionSender.send([tx], this.rpcProvider.connection, {
customErrors: [this.ammClient.program.idl.errors],
CUs: 100_000
});
return this.transactionSender.send(
[tx],
this.rpcProvider.connection,
{
customErrors: [this.ammClient.program.idl.errors],
CUs: 100_000
},
{
title: "Adding Liquidity"
}
);
}

simulateAddLiquidity(
Expand Down Expand Up @@ -377,10 +384,15 @@ export class FutarchyAmmMarketsRPCClient implements FutarchyAmmMarketsClient {
)
.transaction();

return this.transactionSender?.send([tx], this.rpcProvider.connection, {
customErrors: [this.ammClient.program.idl.errors],
CUs: 80_000
});
return this.transactionSender?.send(
[tx],
this.rpcProvider.connection,
{
customErrors: [this.ammClient.program.idl.errors],
CUs: 80_000
},
{ title: "Swapping" }
);
}

async getSwapPreview(
Expand Down
26 changes: 16 additions & 10 deletions lib/client/rpc/market-clients/openbookMarkets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@ export class FutarchyOpenbookMarketsRPCClient
const baseTokenWithSymbol = !baseToken.isFallback
? baseToken
: {
...baseToken,
symbol: marketName.split("/")[0]
};
...baseToken,
symbol: marketName.split("/")[0]
};
const quoteTokenWithSymbol = !quoteToken.isFallback
? quoteToken
: {
...quoteToken,
symbol: marketName.split("/")[0]
};
...quoteToken,
symbol: marketName.split("/")[0]
};

return {
baseMint: obMarket.account.baseMint,
Expand Down Expand Up @@ -295,7 +295,9 @@ export class FutarchyOpenbookMarketsRPCClient
.preInstructions(openTx.instructions)
.transaction();

return this.transactionSender.send([placeTx], this.rpcProvider.connection, { customErrors: [market.twapProgram.idl.errors] });
return this.transactionSender.send([placeTx], this.rpcProvider.connection, {
customErrors: [market.twapProgram.idl.errors]
});
}

async getOrCreateOpenOrdersIndexer({
Expand Down Expand Up @@ -403,21 +405,25 @@ export class FutarchyOpenbookMarketsRPCClient
]
};
const tx = await this.cancelAndSettleFundsTransactions(order, market);
return this.transactionSender.send([tx], this.rpcProvider.connection, { customErrors: [this.openbookClient.program.idl.errors] });
if (tx) {
return this.transactionSender.send([tx], this.rpcProvider.connection, {
customErrors: [this.openbookClient.program.idl.errors]
});
}
}

private async cancelAndSettleFundsTransactions(
order: OpenbookOrder,
market: OpenbookMarket
) {
if (!this.transactionSender) return [];
if (!this.transactionSender) return null;
const openOrders = await OpenOrders.load(
order.owner,
market.marketInstance,
this.openbookClient
);
if (!openOrders) {
return [];
return null;
}

const userBaseAccount = getAssociatedTokenAddressSync(
Expand Down
160 changes: 101 additions & 59 deletions lib/client/rpc/proposals/createProposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { AnchorProvider, Program, BN } from "@coral-xyz/anchor";
import {
AutocratClient,
InstructionUtils,
MaxCUs,
MaxCUs
} from "@metadaoproject/futarchy";
import { OpenBookV2Client } from "@openbook-dex/openbook-v2";
import {
Expand Down Expand Up @@ -95,8 +95,10 @@ export class CreateProposalClient implements CreateProposal {
true
);

const vaultExists = await this.rpcProvider.connection.getAccountInfo(vaultUnderlyingTokenAccount)
if (vaultExists) return [vault, undefined]
const vaultExists = await this.rpcProvider.connection.getAccountInfo(
vaultUnderlyingTokenAccount
);
if (vaultExists) return [vault, undefined];

const ix = (
await vaultProgram.methods
Expand Down Expand Up @@ -205,10 +207,18 @@ export class CreateProposalClient implements CreateProposal {
twapProgram.programId
);

const existingPassBaseMint = (await vaultProgram.account.conditionalVault.fetch(baseVault))?.conditionalOnFinalizeTokenMint
const existingFailBaseMint = (await vaultProgram.account.conditionalVault.fetch(baseVault))?.conditionalOnRevertTokenMint
const existingPassQuoteMint = (await vaultProgram.account.conditionalVault.fetch(quoteVault))?.conditionalOnFinalizeTokenMint
const existingFailQuoteMint = (await vaultProgram.account.conditionalVault.fetch(quoteVault))?.conditionalOnRevertTokenMint
const existingPassBaseMint = (
await vaultProgram.account.conditionalVault.fetch(baseVault)
)?.conditionalOnFinalizeTokenMint;
const existingFailBaseMint = (
await vaultProgram.account.conditionalVault.fetch(baseVault)
)?.conditionalOnRevertTokenMint;
const existingPassQuoteMint = (
await vaultProgram.account.conditionalVault.fetch(quoteVault)
)?.conditionalOnFinalizeTokenMint;
const existingFailQuoteMint = (
await vaultProgram.account.conditionalVault.fetch(quoteVault)
)?.conditionalOnRevertTokenMint;

let [passMarketIx, passMarketSigners] = await openbook.createMarketIx(
this.rpcProvider.publicKey,
Expand Down Expand Up @@ -314,8 +324,6 @@ export class CreateProposalClient implements CreateProposal {
.transaction()
).instructions;



// initializeProposal needs to be a versioned tx to be able to partial sign with wallet signAllTransactions
// signing after a partial sign overwrites it
// versionedTransaction have no partialSign fn because it's sign fn is a partialSign
Expand All @@ -332,11 +340,12 @@ export class CreateProposalClient implements CreateProposal {
createFailMarketTx,
createTwaps,
initializeProposalTx
].filter(tx => tx !== undefined)
].filter((tx) => tx !== undefined);
const txResp = await this.transactionSender?.send(
allTxs,
this.rpcProvider.connection,
{ commitment: "confirmed", sequential: true }
{ commitment: "confirmed", sequential: true },
{ title: "Creating Proposal" }
);

const accounts = {
Expand All @@ -360,21 +369,23 @@ export class CreateProposalClient implements CreateProposal {
onPassIx: ProposalInstructionWithPreinstructions,
marketParams: AmmMarketParams
): SendTransactionResponse {
if (!this.transactionSender) return
if (!this.transactionSender) return;

const nonce = new BN(Math.random() * 2 ** 50);
const proposal = PublicKey.findProgramAddressSync(
[
Buffer.from("proposal"),
this.rpcProvider.publicKey.toBuffer(),
nonce.toArrayLike(Buffer, "le", 8),
nonce.toArrayLike(Buffer, "le", 8)
],
this.autocratClient.autocrat.programId
)[0]
)[0];

const accountInfo = await this.rpcProvider.connection.getAccountInfo(proposal);
const accountInfo = await this.rpcProvider.connection.getAccountInfo(
proposal
);
if (accountInfo !== null) {
this.createProposalV0_3(dao, onPassIx, marketParams)
this.createProposalV0_3(dao, onPassIx, marketParams);
}
const autocrat = this.autocratClient.autocrat;

Expand All @@ -383,28 +394,48 @@ export class CreateProposalClient implements CreateProposal {
const baseTokensToLP = new BN(marketParams.baseLiquidity);
const quoteTokensToLP = new BN(marketParams.quoteLiquidity);

const {
failAmm,
passAmm,
failBaseMint,
failQuoteMint,
failLp,
passBaseMint,
passQuoteMint,
passLp,
baseVault,
quoteVault
} = this.autocratClient.getProposalPdas(
proposal,
daoAccount.tokenMint,
daoAccount.usdcMint,
dao.publicKey
);

const { failAmm, passAmm, failBaseMint, failQuoteMint, failLp, passBaseMint, passQuoteMint, passLp, baseVault, quoteVault } = this.autocratClient.getProposalPdas(proposal, daoAccount.tokenMint, daoAccount.usdcMint, dao.publicKey)

const initializeVaultsAndCreateAmmsTx = await this.autocratClient.vaultClient
.initializeVaultIx(proposal, daoAccount.tokenMint)
.postInstructions(
await InstructionUtils.getInstructions(
this.autocratClient.vaultClient.initializeVaultIx(proposal, daoAccount.usdcMint),
this.autocratClient.ammClient.createAmmIx(
passBaseMint,
passQuoteMint,
daoAccount.twapInitialObservation,
daoAccount.twapMaxObservationChangePerUpdate
),
this.autocratClient.ammClient.createAmmIx(
failBaseMint,
failQuoteMint,
daoAccount.twapInitialObservation,
daoAccount.twapMaxObservationChangePerUpdate
const initializeVaultsAndCreateAmmsTx =
await this.autocratClient.vaultClient
.initializeVaultIx(proposal, daoAccount.tokenMint)
.postInstructions(
await InstructionUtils.getInstructions(
this.autocratClient.vaultClient.initializeVaultIx(
proposal,
daoAccount.usdcMint
),
this.autocratClient.ammClient.createAmmIx(
passBaseMint,
passQuoteMint,
daoAccount.twapInitialObservation,
daoAccount.twapMaxObservationChangePerUpdate
),
this.autocratClient.ammClient.createAmmIx(
failBaseMint,
failQuoteMint,
daoAccount.twapInitialObservation,
daoAccount.twapMaxObservationChangePerUpdate
)
)
)
).transaction()
.transaction();

const mintTx = await this.autocratClient.vaultClient
.mintConditionalTokensIx(baseVault, daoAccount.tokenMint, baseTokensToLP)
Expand All @@ -414,31 +445,33 @@ export class CreateProposalClient implements CreateProposal {
quoteVault,
daoAccount.usdcMint,
quoteTokensToLP
),
)
)
)
.transaction()
.transaction();

const liquidityTx = await this.autocratClient.ammClient.addLiquidityIx(
failAmm,
failBaseMint,
failQuoteMint,
quoteTokensToLP,
baseTokensToLP,
new BN(0)
).postInstructions(
await InstructionUtils.getInstructions(
this.autocratClient.ammClient
.addLiquidityIx(
const liquidityTx = await this.autocratClient.ammClient
.addLiquidityIx(
failAmm,
failBaseMint,
failQuoteMint,
quoteTokensToLP,
baseTokensToLP,
new BN(0)
)
.postInstructions(
await InstructionUtils.getInstructions(
this.autocratClient.ammClient.addLiquidityIx(
passAmm,
passBaseMint,
passQuoteMint,
quoteTokensToLP,
baseTokensToLP,
new BN(0)
)
)
)
).transaction()
.transaction();

const initializeProposalTx = await this.autocratClient
.initializeProposalIx(
Expand All @@ -451,18 +484,26 @@ export class CreateProposalClient implements CreateProposal {
quoteTokensToLP,
nonce
)
.preInstructions([
...(onPassIx.preInstructions || []),
])
.transaction()
.preInstructions([...(onPassIx.preInstructions || [])])
.transaction();

const allTxs = [initializeVaultsAndCreateAmmsTx, mintTx, liquidityTx, initializeProposalTx];
const allTxs = [
initializeVaultsAndCreateAmmsTx,
mintTx,
liquidityTx,
initializeProposalTx
];

//TO DO : recalculate compute units
const initializeVaultsAndAmmCus = MaxCUs.createIdempotent * 2 + MaxCUs.initializeConditionalVault * 2 + MaxCUs.initializeAmm * 2
const mintCus = MaxCUs.createIdempotent * 4 + MaxCUs.mintConditionalTokens * 2 + 50000;
const addLiquidityCus = + MaxCUs.addLiquidity * 2;
const initializeProposalCus = MaxCUs.createIdempotent + MaxCUs.initializeProposal + 50000;
const initializeVaultsAndAmmCus =
MaxCUs.createIdempotent * 2 +
MaxCUs.initializeConditionalVault * 2 +
MaxCUs.initializeAmm * 2;
const mintCus =
MaxCUs.createIdempotent * 4 + MaxCUs.mintConditionalTokens * 2 + 50000;
const addLiquidityCus = +MaxCUs.addLiquidity * 2;
const initializeProposalCus =
MaxCUs.createIdempotent + MaxCUs.initializeProposal + 50000;

const txResp = await this.transactionSender?.send(
allTxs,
Expand All @@ -476,7 +517,8 @@ export class CreateProposalClient implements CreateProposal {
addLiquidityCus,
initializeProposalCus
]
}
},
{ title: "Creating Proposal" }
);

const accounts = {
Expand Down
Loading

0 comments on commit 323feba

Please sign in to comment.