Skip to content

Commit

Permalink
feat/fetch single balance (#128)
Browse files Browse the repository at this point in the history
* feat: single balance fetch method

* fix: always pass in authority to mint for some reason

* chore: version

---------

Co-authored-by: Kollan House <[email protected]>
  • Loading branch information
LukasDeco and R-K-H authored May 30, 2024
1 parent ea93995 commit f68cd18
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 101 deletions.
9 changes: 7 additions & 2 deletions lib/client/indexer/balances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,22 @@ export class FutarchyIndexerBalancesClient implements FutarchyBalancesClient {
quoteToken: TokenProps,
proposalsWithVaults: Proposal[],
passTokenUrl?: string,
failtokenUrl?: string,
failtokenUrl?: string
): Promise<TokenWithBalancePDAAndProposal[]> {
return this.rpcBalancesClient.fetchAllConditionalTokenWalletBalances(
ownerWallet,
baseToken,
quoteToken,
proposalsWithVaults,
passTokenUrl,
failtokenUrl,
failtokenUrl
);
}

async fetchTokenBalance(pda: PublicKey | null, token: TokenProps) {
return this.rpcBalancesClient.fetchTokenBalance(pda, token);
}

watchTokenBalance(tokenWithPDA: TokenWithPDA): Observable<TokenWithBalance> {
return this.rpcBalancesClient.watchTokenBalance(tokenWithPDA);
}
Expand Down
127 changes: 67 additions & 60 deletions lib/client/rpc/balances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import { Proposal } from "@/types/proposals";
import { BN, Provider } from "@coral-xyz/anchor";
import { Observable, retry } from "rxjs";

const PASS_USDC_URL = "https://imagedelivery.net/HYEnlujCFMCgj6yA728xIw/f38677ab-8ec6-4706-6606-7d4e0a3cfc00/public"
const FAIL_USDC_URL = "https://imagedelivery.net/HYEnlujCFMCgj6yA728xIw/d9bfd8de-2937-419a-96f6-8d6a3a76d200/public"
const PASS_USDC_URL =
"https://imagedelivery.net/HYEnlujCFMCgj6yA728xIw/f38677ab-8ec6-4706-6606-7d4e0a3cfc00/public";
const FAIL_USDC_URL =
"https://imagedelivery.net/HYEnlujCFMCgj6yA728xIw/d9bfd8de-2937-419a-96f6-8d6a3a76d200/public";

export class FutarchyRPCBalancesClient implements FutarchyBalancesClient {
private rpcProvider: Provider;
Expand All @@ -43,35 +45,40 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient {
await Promise.all(
Array.from(tokensByMint.values())
.filter((t): t is TokenWithPDA => !!t.pda)
.map<Promise<TokenWithBalance | undefined>>(async (t) => {
try {
const tokenBalance =
await this.rpcProvider.connection.getTokenAccountBalance(
t.pda
);
return {
balance: tokenBalance.value.uiAmount ?? 0,
token: t.token
};
} catch (e) {
if (!JSON.stringify(e).includes("not found")) {
console.info(
"error fetching wallet balance for token:",
t.token.symbol
);
}
return {
balance: 0,
token: t.token
};
}
})
.map<Promise<TokenWithBalance | undefined>>(async (t) =>
this.fetchTokenBalance(t.pda, t.token)
)
)
).filter((b): b is TokenWithBalance => !!b);
}
return [];
}

async fetchTokenBalance(pda: PublicKey | null, token: TokenProps) {
if (!pda)
return {
balance: 0,
token: token
};

try {
const tokenBalance =
await this.rpcProvider.connection.getTokenAccountBalance(pda);
return {
balance: tokenBalance.value.uiAmount ?? 0,
token: token
};
} catch (e) {
if (!JSON.stringify(e).includes("not found")) {
console.info("error fetching wallet balance for token:", token.symbol);
}
return {
balance: 0,
token: token
};
}
}

watchMainTokenWalletBalances(
daoAggregate: DaoAggregate,
ownerWallet: PublicKey
Expand Down Expand Up @@ -101,10 +108,10 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient {
mapping.set(dao.baseToken.publicKey, {
pda: owner
? getAssociatedTokenAddressSync(
new PublicKey(dao.baseToken.publicKey),
owner,
true
)
new PublicKey(dao.baseToken.publicKey),
owner,
true
)
: null,
token: dao.baseToken
});
Expand All @@ -113,10 +120,10 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient {
mapping.set(dao.quoteToken.publicKey, {
pda: owner
? getAssociatedTokenAddressSync(
new PublicKey(dao.quoteToken.publicKey),
owner,
true
)
new PublicKey(dao.quoteToken.publicKey),
owner,
true
)
: null,
token: dao.quoteToken
});
Expand Down Expand Up @@ -183,7 +190,7 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient {
quoteToken: TokenProps,
proposals: Proposal[],
passTokenUrl?: string,
failTokenUrl?: string,
failTokenUrl?: string
): Promise<TokenWithBalancePDAAndProposal[]> {
const tokenBalances = await Promise.all(
proposals.map(async (proposal) => {
Expand All @@ -193,12 +200,12 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient {
{
pda: ownerWallet
? getAssociatedTokenAddressSync(
new PublicKey(
proposal.baseVaultAccount.conditionalOnFinalizeTokenMint
),
ownerWallet,
true
)
new PublicKey(
proposal.baseVaultAccount.conditionalOnFinalizeTokenMint
),
ownerWallet,
true
)
: null,
token: {
...baseToken,
Expand All @@ -212,12 +219,12 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient {
{
pda: ownerWallet
? getAssociatedTokenAddressSync(
new PublicKey(
proposal.baseVaultAccount.conditionalOnRevertTokenMint
),
ownerWallet,
true
)
new PublicKey(
proposal.baseVaultAccount.conditionalOnRevertTokenMint
),
ownerWallet,
true
)
: null,
token: {
...baseToken,
Expand All @@ -231,12 +238,12 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient {
{
pda: ownerWallet
? getAssociatedTokenAddressSync(
new PublicKey(
proposal.quoteVaultAccount.conditionalOnFinalizeTokenMint
),
ownerWallet,
true
)
new PublicKey(
proposal.quoteVaultAccount.conditionalOnFinalizeTokenMint
),
ownerWallet,
true
)
: null,
token: {
...quoteToken,
Expand All @@ -250,12 +257,12 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient {
{
pda: ownerWallet
? getAssociatedTokenAddressSync(
new PublicKey(
proposal.quoteVaultAccount.conditionalOnRevertTokenMint
),
ownerWallet,
true
)
new PublicKey(
proposal.quoteVaultAccount.conditionalOnRevertTokenMint
),
ownerWallet,
true
)
: null,
token: {
...quoteToken,
Expand All @@ -273,8 +280,8 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient {
try {
const tokenBalance = t.pda
? await this.rpcProvider.connection.getTokenAccountBalance(
t.pda
)
t.pda
)
: { value: { uiAmount: 0 } };
return {
balance: tokenBalance.value.uiAmount ?? 0,
Expand Down
95 changes: 57 additions & 38 deletions lib/client/rpc/proposals/proposals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,31 @@ export class FutarchyRPCProposalsClient implements FutarchyProposalsClient {
vaultAccount.conditionalOnFinalizeTokenMint,
this.rpcProvider
);
const ixs = [
const accounts = {
vault: vaultAccountAddress,
userConditionalOnFinalizeTokenAccount: getAssociatedTokenAddressSync(
vaultAccount.conditionalOnFinalizeTokenMint,
this.rpcProvider.publicKey,
true
),
userConditionalOnRevertTokenAccount: getAssociatedTokenAddressSync(
vaultAccount.conditionalOnRevertTokenMint,
this.rpcProvider.publicKey,
true
),
userUnderlyingTokenAccount: getAssociatedTokenAddressSync(
vaultAccount.underlyingTokenMint,
this.rpcProvider.publicKey,
true
),
vaultUnderlyingTokenAccount: vaultAccount.underlyingTokenAccount,
conditionalOnFinalizeTokenMint:
vaultAccount.conditionalOnFinalizeTokenMint,
conditionalOnRevertTokenMint: vaultAccount.conditionalOnRevertTokenMint,
// we used to not need to pass this in, but since we changed some things on the frontend now we do ¯\_(ツ)_/¯
authority: this.transactionSender.owner
};
const finalizeTokenPDACreateIx =
createAssociatedTokenAccountIdempotentInstruction(
this.rpcProvider.publicKey,
getAssociatedTokenAddressSync(
Expand All @@ -152,7 +176,8 @@ export class FutarchyRPCProposalsClient implements FutarchyProposalsClient {
),
this.rpcProvider.publicKey,
vaultAccount.conditionalOnFinalizeTokenMint
),
);
const revertTokenPDACreateIx =
createAssociatedTokenAccountIdempotentInstruction(
this.rpcProvider.publicKey,
getAssociatedTokenAddressSync(
Expand All @@ -162,39 +187,21 @@ export class FutarchyRPCProposalsClient implements FutarchyProposalsClient {
),
this.rpcProvider.publicKey,
vaultAccount.conditionalOnRevertTokenMint
),
await vaultAccount.protocol.vault.methods
.mintConditionalTokens(
new BN(
numeral(amount)
.multiply(10 ** (decimals || 0))
.format("0")
)
);
const mintConditionalsIx = await vaultAccount.protocol.vault.methods
.mintConditionalTokens(
new BN(
numeral(amount)
.multiply(10 ** (decimals || 0))
.format("0")
)
.accounts({
vault: vaultAccountAddress,
userConditionalOnFinalizeTokenAccount: getAssociatedTokenAddressSync(
vaultAccount.conditionalOnFinalizeTokenMint,
this.rpcProvider.publicKey,
true
),
userConditionalOnRevertTokenAccount: getAssociatedTokenAddressSync(
vaultAccount.conditionalOnRevertTokenMint,
this.rpcProvider.publicKey,
true
),
userUnderlyingTokenAccount: getAssociatedTokenAddressSync(
vaultAccount.underlyingTokenMint,
this.rpcProvider.publicKey,
true
),
vaultUnderlyingTokenAccount: vaultAccount.underlyingTokenAccount,
conditionalOnFinalizeTokenMint:
vaultAccount.conditionalOnFinalizeTokenMint,
conditionalOnRevertTokenMint:
vaultAccount.conditionalOnRevertTokenMint
})
.instruction()
)
.accounts(accounts)
.instruction();
const ixs = [
finalizeTokenPDACreateIx,
revertTokenPDACreateIx,
mintConditionalsIx
];
const tx = new Transaction().add(...ixs);
return this.transactionSender.send([tx], this.rpcProvider.connection);
Expand Down Expand Up @@ -261,8 +268,15 @@ export class FutarchyRPCProposalsClient implements FutarchyProposalsClient {
underlyingToken: "base" | "quote"
) {
if (programVersion == "V0.3" || programVersion == "V0.2") {
const vaultForVersion = autocratVersionToConditionalVaultMap[proposal.protocol.deploymentVersion]
const vaultProgram = new Program(vaultForVersion.idl, vaultForVersion.programId, this.rpcProvider)
const vaultForVersion =
autocratVersionToConditionalVaultMap[
proposal.protocol.deploymentVersion
];
const vaultProgram = new Program(
vaultForVersion.idl,
vaultForVersion.programId,
this.rpcProvider
);

const vaultAccount =
underlyingToken == "base"
Expand Down Expand Up @@ -295,8 +309,13 @@ export class FutarchyRPCProposalsClient implements FutarchyProposalsClient {
}

public async withdraw(proposal: Proposal) {
const vaultForVersion = autocratVersionToConditionalVaultMap[proposal.protocol.deploymentVersion]
const vaultProgram = new Program(vaultForVersion.idl, vaultForVersion.programId, this.rpcProvider)
const vaultForVersion =
autocratVersionToConditionalVaultMap[proposal.protocol.deploymentVersion];
const vaultProgram = new Program(
vaultForVersion.idl,
vaultForVersion.programId,
this.rpcProvider
);

const baseAccounts = await this.getVaultAccounts(
proposal.baseVaultAccount,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@metadaoproject/futarchy-sdk",
"version": "2.0.0-alpha.21",
"version": "2.0.0-alpha.23",
"main": "dist",
"scripts": {
"preinstall": "npx only-allow pnpm",
Expand Down

0 comments on commit f68cd18

Please sign in to comment.