Skip to content

Commit

Permalink
Fixing merge.
Browse files Browse the repository at this point in the history
  • Loading branch information
blockiosaurus committed Feb 21, 2024
2 parents c86a618 + 1a56b2a commit caef182
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 23 deletions.
13 changes: 13 additions & 0 deletions clients/js/src/generated/errors/mplAsset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,19 @@ export class PluginAlreadyExistsError extends ProgramError {
codeToErrorMap.set(0xf, PluginAlreadyExistsError);
nameToErrorMap.set('PluginAlreadyExists', PluginAlreadyExistsError);

/** NumericalOverflowError: Numerical overflow */
export class NumericalOverflowErrorError extends ProgramError {
readonly name: string = 'NumericalOverflowError';

readonly code: number = 0x10; // 16

constructor(program: Program, cause?: Error) {
super('Numerical overflow', program, cause);
}
}
codeToErrorMap.set(0x10, NumericalOverflowErrorError);
nameToErrorMap.set('NumericalOverflowError', NumericalOverflowErrorError);

/**
* Attempts to resolve a custom program error from the provided error code.
* @category Errors
Expand Down
39 changes: 32 additions & 7 deletions clients/js/src/generated/instructions/burn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import {
Context,
Option,
OptionOrNullable,
Pda,
PublicKey,
Signer,
Expand All @@ -17,6 +19,7 @@ import {
import {
Serializer,
mapSerializer,
option,
struct,
u8,
} from '@metaplex-foundation/umi/serializers';
Expand All @@ -25,6 +28,11 @@ import {
ResolvedAccountsWithIndices,
getAccountMetasAndSigners,
} from '../shared';
import {
CompressionProof,
CompressionProofArgs,
getCompressionProofSerializer,
} from '../types';

// Accounts.
export type BurnInstructionAccounts = {
Expand All @@ -41,26 +49,38 @@ export type BurnInstructionAccounts = {
};

// Data.
export type BurnInstructionData = { discriminator: number };
export type BurnInstructionData = {
discriminator: number;
compressionProof: Option<CompressionProof>;
};

export type BurnInstructionDataArgs = {};
export type BurnInstructionDataArgs = {
compressionProof: OptionOrNullable<CompressionProofArgs>;
};

export function getBurnInstructionDataSerializer(): Serializer<
BurnInstructionDataArgs,
BurnInstructionData
> {
return mapSerializer<BurnInstructionDataArgs, any, BurnInstructionData>(
struct<BurnInstructionData>([['discriminator', u8()]], {
description: 'BurnInstructionData',
}),
struct<BurnInstructionData>(
[
['discriminator', u8()],
['compressionProof', option(getCompressionProofSerializer())],
],
{ description: 'BurnInstructionData' }
),
(value) => ({ ...value, discriminator: 5 })
) as Serializer<BurnInstructionDataArgs, BurnInstructionData>;
}

// Args.
export type BurnInstructionArgs = BurnInstructionDataArgs;

// Instruction.
export function burn(
context: Pick<Context, 'identity' | 'programs'>,
input: BurnInstructionAccounts
input: BurnInstructionAccounts & BurnInstructionArgs
): TransactionBuilder {
// Program ID.
const programId = context.programs.getPublicKey(
Expand All @@ -85,6 +105,9 @@ export function burn(
},
};

// Arguments.
const resolvedArgs: BurnInstructionArgs = { ...input };

// Default values.
if (!resolvedAccounts.authority.value) {
resolvedAccounts.authority.value = context.identity;
Expand All @@ -103,7 +126,9 @@ export function burn(
);

// Data.
const data = getBurnInstructionDataSerializer().serialize({});
const data = getBurnInstructionDataSerializer().serialize(
resolvedArgs as BurnInstructionDataArgs
);

// Bytes Created On Chain.
const bytesCreatedOnChain = 0;
Expand Down
87 changes: 87 additions & 0 deletions clients/js/test/burn.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { assertAccountExists, generateSigner, sol} from '@metaplex-foundation/umi';
import test from 'ava';
// import { base58 } from '@metaplex-foundation/umi/serializers';
import { Asset, DataState, create, fetchAsset, burn, Key } from '../src';
import { createUmi } from './_setup';

test('it can burn an asset as the owner', async (t) => {
// Given a Umi instance and a new signer.
const umi = await createUmi();
const assetAddress = generateSigner(umi);

// When we create a new account.
await create(umi, {
dataState: DataState.AccountState,
assetAddress,
name: 'Test Bread',
uri: 'https://example.com/bread',
}).sendAndConfirm(umi);

// Then an account was created with the correct data.
const beforeAsset = await fetchAsset(umi, assetAddress.publicKey);
// console.log("Account State:", beforeAsset);
t.like(beforeAsset, <Asset>{
publicKey: assetAddress.publicKey,
updateAuthority: umi.identity.publicKey,
owner: umi.identity.publicKey,
name: 'Test Bread',
uri: 'https://example.com/bread',
});

await burn(umi, {
assetAddress: assetAddress.publicKey,
compressionProof: null
}).sendAndConfirm(umi);

// And the asset address still exists but was resized to 1.
const afterAsset = await umi.rpc.getAccount(assetAddress.publicKey);
t.true(afterAsset.exists);
assertAccountExists(afterAsset);
t.deepEqual(afterAsset.lamports, sol(0.00089784));
t.is(afterAsset.data.length, 1);
t.is(afterAsset.data[0], Key.Uninitialized);
});

test('it cannot burn an asset if not the owner', async (t) => {
// Given a Umi instance and a new signer.
const umi = await createUmi();
const assetAddress = generateSigner(umi);
const attacker = generateSigner(umi);

// When we create a new account.
await create(umi, {
dataState: DataState.AccountState,
assetAddress,
name: 'Test Bread',
uri: 'https://example.com/bread',
}).sendAndConfirm(umi);

// Then an account was created with the correct data.
const beforeAsset = await fetchAsset(umi, assetAddress.publicKey);
// console.log("Account State:", beforeAsset);
t.like(beforeAsset, <Asset>{
publicKey: assetAddress.publicKey,
updateAuthority: umi.identity.publicKey,
owner: umi.identity.publicKey,
name: 'Test Bread',
uri: 'https://example.com/bread',
});

const result = burn(umi, {
assetAddress: assetAddress.publicKey,
compressionProof: null,
authority: attacker,
}).sendAndConfirm(umi);

await t.throwsAsync(result, { name: 'InvalidAuthority' })

const afterAsset = await fetchAsset(umi, assetAddress.publicKey);
// console.log("Account State:", afterAsset);
t.like(afterAsset, <Asset>{
publicKey: assetAddress.publicKey,
updateAuthority: umi.identity.publicKey,
owner: umi.identity.publicKey,
name: 'Test Bread',
uri: 'https://example.com/bread',
});
});
3 changes: 3 additions & 0 deletions clients/rust/src/generated/errors/mpl_asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ pub enum MplAssetError {
/// 15 (0xF) - Plugin already exists
#[error("Plugin already exists")]
PluginAlreadyExists,
/// 16 (0x10) - Numerical overflow
#[error("Numerical overflow")]
NumericalOverflowError,
}

impl solana_program::program_error::PrintProgramError for MplAssetError {
Expand Down
51 changes: 46 additions & 5 deletions clients/rust/src/generated/instructions/burn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//! [https://github.com/metaplex-foundation/kinobi]
//!
use crate::generated::types::CompressionProof;
use borsh::BorshDeserialize;
use borsh::BorshSerialize;

Expand All @@ -23,12 +24,16 @@ pub struct Burn {
}

impl Burn {
pub fn instruction(&self) -> solana_program::instruction::Instruction {
self.instruction_with_remaining_accounts(&[])
pub fn instruction(
&self,
args: BurnInstructionArgs,
) -> solana_program::instruction::Instruction {
self.instruction_with_remaining_accounts(args, &[])
}
#[allow(clippy::vec_init_then_push)]
pub fn instruction_with_remaining_accounts(
&self,
args: BurnInstructionArgs,
remaining_accounts: &[solana_program::instruction::AccountMeta],
) -> solana_program::instruction::Instruction {
let mut accounts = Vec::with_capacity(5 + remaining_accounts.len());
Expand Down Expand Up @@ -70,7 +75,9 @@ impl Burn {
));
}
accounts.extend_from_slice(remaining_accounts);
let data = BurnInstructionData::new().try_to_vec().unwrap();
let mut data = BurnInstructionData::new().try_to_vec().unwrap();
let mut args = args.try_to_vec().unwrap();
data.append(&mut args);

solana_program::instruction::Instruction {
program_id: crate::MPL_ASSET_ID,
Expand All @@ -91,6 +98,12 @@ impl BurnInstructionData {
}
}

#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BurnInstructionArgs {
pub compression_proof: Option<CompressionProof>,
}

/// Instruction builder.
#[derive(Default)]
pub struct BurnBuilder {
Expand All @@ -99,6 +112,7 @@ pub struct BurnBuilder {
authority: Option<solana_program::pubkey::Pubkey>,
payer: Option<solana_program::pubkey::Pubkey>,
log_wrapper: Option<solana_program::pubkey::Pubkey>,
compression_proof: Option<CompressionProof>,
__remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
}

Expand Down Expand Up @@ -142,6 +156,12 @@ impl BurnBuilder {
self.log_wrapper = log_wrapper;
self
}
/// `[optional argument]`
#[inline(always)]
pub fn compression_proof(&mut self, compression_proof: CompressionProof) -> &mut Self {
self.compression_proof = Some(compression_proof);
self
}
/// Add an aditional account to the instruction.
#[inline(always)]
pub fn add_remaining_account(
Expand Down Expand Up @@ -169,8 +189,11 @@ impl BurnBuilder {
payer: self.payer,
log_wrapper: self.log_wrapper,
};
let args = BurnInstructionArgs {
compression_proof: self.compression_proof.clone(),
};

accounts.instruction_with_remaining_accounts(&self.__remaining_accounts)
accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts)
}
}

Expand Down Expand Up @@ -202,12 +225,15 @@ pub struct BurnCpi<'a, 'b> {
pub payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
/// The SPL Noop Program
pub log_wrapper: Option<&'b solana_program::account_info::AccountInfo<'a>>,
/// The arguments for the instruction.
pub __args: BurnInstructionArgs,
}

impl<'a, 'b> BurnCpi<'a, 'b> {
pub fn new(
program: &'b solana_program::account_info::AccountInfo<'a>,
accounts: BurnCpiAccounts<'a, 'b>,
args: BurnInstructionArgs,
) -> Self {
Self {
__program: program,
Expand All @@ -216,6 +242,7 @@ impl<'a, 'b> BurnCpi<'a, 'b> {
authority: accounts.authority,
payer: accounts.payer,
log_wrapper: accounts.log_wrapper,
__args: args,
}
}
#[inline(always)]
Expand Down Expand Up @@ -299,7 +326,9 @@ impl<'a, 'b> BurnCpi<'a, 'b> {
is_writable: remaining_account.2,
})
});
let data = BurnInstructionData::new().try_to_vec().unwrap();
let mut data = BurnInstructionData::new().try_to_vec().unwrap();
let mut args = self.__args.try_to_vec().unwrap();
data.append(&mut args);

let instruction = solana_program::instruction::Instruction {
program_id: crate::MPL_ASSET_ID,
Expand Down Expand Up @@ -345,6 +374,7 @@ impl<'a, 'b> BurnCpiBuilder<'a, 'b> {
authority: None,
payer: None,
log_wrapper: None,
compression_proof: None,
__remaining_accounts: Vec::new(),
});
Self { instruction }
Expand Down Expand Up @@ -397,6 +427,12 @@ impl<'a, 'b> BurnCpiBuilder<'a, 'b> {
self.instruction.log_wrapper = log_wrapper;
self
}
/// `[optional argument]`
#[inline(always)]
pub fn compression_proof(&mut self, compression_proof: CompressionProof) -> &mut Self {
self.instruction.compression_proof = Some(compression_proof);
self
}
/// Add an additional account to the instruction.
#[inline(always)]
pub fn add_remaining_account(
Expand Down Expand Up @@ -438,6 +474,9 @@ impl<'a, 'b> BurnCpiBuilder<'a, 'b> {
&self,
signers_seeds: &[&[&[u8]]],
) -> solana_program::entrypoint::ProgramResult {
let args = BurnInstructionArgs {
compression_proof: self.instruction.compression_proof.clone(),
};
let instruction = BurnCpi {
__program: self.instruction.__program,

Expand All @@ -453,6 +492,7 @@ impl<'a, 'b> BurnCpiBuilder<'a, 'b> {
payer: self.instruction.payer,

log_wrapper: self.instruction.log_wrapper,
__args: args,
};
instruction.invoke_signed_with_remaining_accounts(
signers_seeds,
Expand All @@ -468,6 +508,7 @@ struct BurnCpiBuilderInstruction<'a, 'b> {
authority: Option<&'b solana_program::account_info::AccountInfo<'a>>,
payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
log_wrapper: Option<&'b solana_program::account_info::AccountInfo<'a>>,
compression_proof: Option<CompressionProof>,
/// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`.
__remaining_accounts: Vec<(
&'b solana_program::account_info::AccountInfo<'a>,
Expand Down
Loading

0 comments on commit caef182

Please sign in to comment.