Skip to content

Commit

Permalink
Complete the adding of metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
metaproph3t committed Aug 26, 2024
1 parent 0640a13 commit d0bf35f
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 29 deletions.
2 changes: 2 additions & 0 deletions programs/conditional_vault/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ pub enum VaultError {
ConditionalTokenMintMismatch,
#[msg("Payouts must sum to 1 or more")]
PayoutZero,
#[msg("Conditional token metadata already set")]
ConditionalTokenMetadataAlreadySet,
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ pub mod proph3t_deployer {

#[derive(AnchorSerialize, AnchorDeserialize)]
pub struct AddMetadataToConditionalTokensArgs {
// pub uri: String,
pub name: String,
pub symbol: String,
pub image: String,
Expand All @@ -24,7 +23,6 @@ pub struct AddMetadataToConditionalTokens<'info> {
#[account(
mut,
mint::authority = vault,
mint::freeze_authority = vault,
)]
pub conditional_token_mint: Account<'info, Mint>,
/// CHECK: verified via cpi into token metadata
Expand All @@ -42,6 +40,11 @@ impl AddMetadataToConditionalTokens<'_> {
// VaultError::VaultAlreadySettled
// );

require!(
self.conditional_token_metadata.data_is_empty(),
VaultError::ConditionalTokenMetadataAlreadySet
);

#[cfg(feature = "production")]
require_eq!(
self.payer.key(), proph3t_deployer::ID
Expand Down
2 changes: 1 addition & 1 deletion programs/conditional_vault/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anchor_lang::prelude::*;
use anchor_spl::metadata::{
create_metadata_accounts_v3, mpl_token_metadata::types::DataV2, CreateMetadataAccountsV3,
Metadata, MetadataAccount,
Metadata,
};
use anchor_spl::{
associated_token::AssociatedToken,
Expand Down
56 changes: 30 additions & 26 deletions sdk/src/ConditionalVaultClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,45 +422,49 @@ export class ConditionalVaultClient {

addMetadataToConditionalTokensIx(
vault: PublicKey,
underlyingTokenMint: PublicKey,
proposalNumber: number,
onFinalizeUri: string,
onRevertUri: string
index: number,
name: string,
symbol: string,
image: string
// underlyingTokenMint: PublicKey,
// proposalNumber: number,
// onFinalizeUri: string,
// onRevertUri: string
) {
const [underlyingTokenMetadata] = getMetadataAddr(underlyingTokenMint);
// const [underlyingTokenMetadata] = getMetadataAddr(underlyingTokenMint);

const [conditionalOnFinalizeTokenMint] = getVaultFinalizeMintAddr(
this.vaultProgram.programId,
vault
);
const [conditionalOnRevertTokenMint] = getVaultRevertMintAddr(
const [conditionalTokenMint] = getConditionalTokenMintAddr(
this.vaultProgram.programId,
vault
vault,
index
);

const [conditionalOnFinalizeTokenMetadata] = getMetadataAddr(
conditionalOnFinalizeTokenMint
);
// const [conditionalOnFinalizeTokenMint] = getVaultFinalizeMintAddr(
// this.vaultProgram.programId,
// vault
// );
// const [conditionalOnRevertTokenMint] = getVaultRevertMintAddr(
// this.vaultProgram.programId,
// vault
// );

const [conditionalOnRevertTokenMetadata] = getMetadataAddr(
conditionalOnRevertTokenMint
);
const [conditionalTokenMetadata] = getMetadataAddr(conditionalTokenMint);

// const [conditionalOnRevertTokenMetadata] = getMetadataAddr(
// conditionalOnRevertTokenMint
// );

return this.vaultProgram.methods
.addMetadataToConditionalTokens({
proposalNumber: new BN(proposalNumber),
onFinalizeUri,
onRevertUri,
name,
symbol,
image,
})
.accounts({
payer: this.provider.publicKey,
vault,
underlyingTokenMint,
underlyingTokenMetadata,
conditionalOnFinalizeTokenMint,
conditionalOnRevertTokenMint,
conditionalOnFinalizeTokenMetadata,
conditionalOnRevertTokenMetadata,
conditionalTokenMint,
conditionalTokenMetadata,
tokenMetadataProgram: MPL_TOKEN_METADATA_PROGRAM_ID,
});
}
Expand Down
10 changes: 10 additions & 0 deletions sdk/src/types/conditional_vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,11 @@ export type ConditionalVault = {
code: 6013;
name: "PayoutZero";
msg: "Payouts must sum to 1 or more";
},
{
code: 6014;
name: "ConditionalTokenMetadataAlreadySet";
msg: "Conditional token metadata already set";
}
];
};
Expand Down Expand Up @@ -1001,5 +1006,10 @@ export const IDL: ConditionalVault = {
name: "PayoutZero",
msg: "Payouts must sum to 1 or more",
},
{
code: 6014,
name: "ConditionalTokenMetadataAlreadySet",
msg: "Conditional token metadata already set",
},
],
};
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ export default async function test() {
const vault = await vaultClient.initializeVault(question, USDC, 2);
const storedVault = await vaultClient.fetchVault(vault);

await vaultClient.addMetadataToConditionalTokensIx(vault, 0, "Trump Share", "TRUMP", "https://example.com/trump.png").rpc();
await vaultClient.addMetadataToConditionalTokensIx(vault, 1, "Harris Share", "HARRIS", "https://example.com/harris.png").rpc();

await vaultClient
.splitTokensIx(question, vault, USDC, new BN(100), 2, alice.publicKey)
.signers([alice])
Expand Down
2 changes: 2 additions & 0 deletions tests/conditionalVault/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import resolveQuestion from "./unit/resolveQuestion.test";
import splitTokens from "./unit/splitTokens.test";
import mergeTokens from "./unit/mergeTokens.test";
import redeemTokens from "./unit/redeemTokens.test";
import addMetadataToConditionalTokens from "./unit/addMetadataToConditionalTokens.test";
import binaryPredictionMarket from "./integration/binaryPredictionMarket.test";
import scalarGrantMarket from "./integration/scalarGrantMarket.test";

Expand All @@ -16,4 +17,5 @@ export default function suite() {
describe("#split_tokens", splitTokens);
describe("#merge_tokens", mergeTokens);
describe("#redeem_tokens", redeemTokens);
describe("#add_metadata_to_conditional_tokens", addMetadataToConditionalTokens);
}
109 changes: 109 additions & 0 deletions tests/conditionalVault/unit/addMetadataToConditionalTokens.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { sha256, ConditionalVaultClient, getConditionalTokenMintAddr, getMetadataAddr } from "@metadaoproject/futarchy";
import { Keypair, PublicKey } from "@solana/web3.js";
import { assert } from "chai";
import { createMint } from "spl-token-bankrun";
import * as anchor from "@coral-xyz/anchor";
import { expectError } from "../../utils";
import { Metadata, deserializeMetadata, getMetadataAccountDataSerializer } from "@metaplex-foundation/mpl-token-metadata";

export default function suite() {
let vaultClient: ConditionalVaultClient;
let question: PublicKey;
let vault: PublicKey;
let underlyingTokenMint: PublicKey;

const metadataSerializer = getMetadataAccountDataSerializer();

before(function () {
vaultClient = this.vaultClient;
});

async function setupVault(outcomes: number) {
let questionId = sha256(new Uint8Array([1, 2, 3]));
let oracle = Keypair.generate();

question = await vaultClient.initializeQuestion(
questionId,
oracle.publicKey,
outcomes
);

underlyingTokenMint = await createMint(
this.banksClient,
this.payer,
this.payer.publicKey,
null,
8
);

vault = await vaultClient.initializeVault(question, underlyingTokenMint, outcomes);
}

async function addMetadataToConditionalTokens(outcomes: number) {
for (let i = 0; i < outcomes; i++) {
await vaultClient.addMetadataToConditionalTokensIx(

Check failure on line 44 in tests/conditionalVault/unit/addMetadataToConditionalTokens.test.ts

View workflow job for this annotation

GitHub Actions / run-anchor-test

Property 'addMetadataToConditionalTokensIx' does not exist on type 'ConditionalVaultClient'.
vault,
i,
`Outcome ${i}`,
`OUT${i}`,
`https://example.com/image${i}.png`
).rpc();
}
}

async function verifyMetadata(outcomes: number) {
for (let i = 0; i < outcomes; i++) {
const [conditionalTokenMint] = getConditionalTokenMintAddr(
vaultClient.vaultProgram.programId,
vault,
i
);

const storedMetadata = await this.banksClient.getAccount(getMetadataAddr(conditionalTokenMint)[0]);
assert.isNotNull(storedMetadata);
const metadata = metadataSerializer.deserialize(storedMetadata.data)[0];
assert.equal(metadata.name, `Outcome ${i}`);
assert.equal(metadata.symbol, `OUT${i}`);
const expectedUri = `data:,{"name":"${metadata.name}","symbol":"${metadata.symbol}","image":"https://example.com/image${i}.png"}`;
assert.equal(metadata.uri, expectedUri);
}
}

it("adds metadata to 2-token vault", async function () {
await setupVault.call(this, 2);
await addMetadataToConditionalTokens(2);
await verifyMetadata.call(this, 2);
});

it("adds metadata to 3-token vault", async function () {
await setupVault.call(this, 3);
await addMetadataToConditionalTokens(3);
await verifyMetadata.call(this, 3);
});

it("adds metadata to 10-token vault", async function () {
await setupVault.call(this, 10);
await addMetadataToConditionalTokens(10);
await verifyMetadata.call(this, 10);
});

it("cannot add metadata twice for the same conditional token", async function () {
await setupVault.call(this, 2);
await addMetadataToConditionalTokens(2);

const callbacks = expectError(
"ConditionalTokenMetadataAlreadySet",
"added metadata to a conditional token that already had metadata"
);

await vaultClient.addMetadataToConditionalTokensIx(

Check failure on line 99 in tests/conditionalVault/unit/addMetadataToConditionalTokens.test.ts

View workflow job for this annotation

GitHub Actions / run-anchor-test

Property 'addMetadataToConditionalTokensIx' does not exist on type 'ConditionalVaultClient'.
vault,
0,
"New Outcome",
"NEW",
"https://example.com/new.png"
)
.rpc()
.then(callbacks[0], callbacks[1]);
});
}

0 comments on commit d0bf35f

Please sign in to comment.