Skip to content

Commit

Permalink
Update metadata into main (#68)
Browse files Browse the repository at this point in the history
* Update metadata (#44)

Original design discussion PR: metaplex-foundation/metaplex-program-library#1121

Original merged PR: #3

---------

* fix protocol conflicts

* allow updating creators without new verifications

* cleanup

* conflicts

* conflicts

* all tests included

* regen solita and fix bugs

* small fixes

* nit

* address code review, without additional test

* added creator verification test

* Regenerate js client

* Rename old_metadata to current_metadata

* Use UpdateArgs to group new metadata params

* Prevent existing verified creators from being removed

Exception: allow verification/unverification during metadata
update for the signer of the tx.

* Derive Default on UpdateArgs

* Fix typo

* Regenerate IDL, Rust client and Umi client

* Regenerate js-solita

* Add canopy to JS Solita test since it uses 2 nodes

* Run CI on any PR

* Removing SetDecompressableState from pub enum InstructionName

* Remove `update_metadata_collection_nft` instruction (#47)

* Remove update_metadata_collection_nft ix

* Remove unneeded checks and errors

* Regenerate IDL and clients

* Update Solita test

---------

Co-authored-by: Sam Orend <[email protected]>

* Avoid inlining UpdateArgs (#50)

* Adding LeafSchemaEvent struct to Rust client

* Add leaf schema accessors to program and Rust client

* Add InstructionName::UpdateMetadata to Rust client

* chore: Release mpl-bubblegum version 1.0.1-beta.1

* Add borsh version range (#54)

* Add borsh version range

* Update lock file

* chore: Release mpl-bubblegum version 1.0.1-beta.2

* Remove optional metadata buffer account from update_metadata

* Update Rust and Umi JS clients, update IDL

* Update js-solita client

* Fixing rust client cargo lock after release downgrades it

* chore: Release mpl-bubblegum version 1.0.1-beta.3

* Delete and regenerate rust client Cargo.lock after release downgrades borsh 0.10.3

* Add update_metadata_collection_nft

* Regenerate clients

* Regenerate Solita JS client

* update Solita tests

* Fix path to js test script

* Remove signer req for tree delegate on update_metadata_collection_nft

* Regenerate Solita JS client

* Add tests for using correct ix based on if item is in collection

* Combine update_metadata and update_metadata_collection_nft

* Regenerate JS and Rust clients

* Regenerate Solita JS client

* Update Solita tests

* Removed unneeded instruction name

* Regenerate IDL

* Clean up README and add update_metadata

* Add updateArgs and fix links

* Remove redundancies and clarify

* chore: Release mpl-bubblegum version 1.0.1-beta.4

---------

Co-authored-by: Sam Orend <[email protected]>
Co-authored-by: Fernando Otero <[email protected]>
Co-authored-by: febo <[email protected]>
Co-authored-by: danenbm <[email protected]>
  • Loading branch information
5 people authored Jan 12, 2024
1 parent 34cd5cb commit 1b119a8
Show file tree
Hide file tree
Showing 35 changed files with 5,271 additions and 518 deletions.
1 change: 0 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ on:
push:
branches: [main]
pull_request:
branches: [main]

env:
CACHE: true
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ You will then have access to the following commands.
- `pnpm programs:test` - Runs BPF tests for all programs (logs disabled).
- `pnpm programs:debug` - Runs BPF tests for all programs.
- `pnpm programs:clean` - Deletes all generated program binaries.
- `clients:rust:test` - Runs BPF tests for the Rust client SDK.
- `clients:js:test` - Runs the JavaScript tests (you must first start the local validator `pnpm validator`).
- `pnpm clients:rust:test` - Runs BPF tests for the Rust client SDK.
- `pnpm clients:js:test` - Runs the JavaScript tests (you must first start the local validator `pnpm validator`).
- `pnpm generate` - Shortcut for `pnpm generate:idls && pnpm generate:clients`.
- `pnpm generate:idls` - Generate IDLs for all programs, as configured in the `configs/shank.cjs` file.
- `pnpm generate:clients` - Generate clients using Kinobi, as configured in the `configs/kinobi.cjs` file.
Expand Down
5 changes: 3 additions & 2 deletions clients/js-solita/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"run-tests": "jest tests --detectOpenHandles",
"test": "start-server-and-test start-validator http://localhost:8899/health run-tests",
"api:gen": "DEBUG='(solita|rustbin):(info|error)' solita",
"lint": "eslint \"{src,test}/**/*.ts\" --format stylish",
"lint": "eslint \"{src,tests}/**/*.ts\" --format stylish",
"fix:lint": "yarn lint --fix",
"prettier": "prettier \"{src,test}/**/*.ts\" --check",
"fix:prettier": "prettier --write src/",
Expand Down Expand Up @@ -54,12 +54,13 @@
"@metaplex-foundation/amman": "0.12.1",
"@metaplex-foundation/rustbin": "^0.3.5",
"@metaplex-foundation/solita": "0.20.0",
"@metaplex-foundation/js": "^0.19.4",
"@solana/spl-account-compression": "^0.1.4",
"@types/bn.js": "^5.1.1",
"@types/chai": "^4.3.0",
"@types/jest": "^29.1.1",
"@types/mocha": "^9.0.0",
"@types/tape": "^4.13.2",
"@types/bn.js": "^5.1.1",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"chai": "^4.3.4",
Expand Down
129 changes: 129 additions & 0 deletions clients/js-solita/src/generated/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,135 @@ export class DecompressionDisabledError extends Error {
createErrorFromCodeLookup.set(0x1791, () => new DecompressionDisabledError());
createErrorFromNameLookup.set('DecompressionDisabled', () => new DecompressionDisabledError());

/**
* MissingCollectionMintAccount: 'Missing collection mint account'
*
* @category Errors
* @category generated
*/
export class MissingCollectionMintAccountError extends Error {
readonly code: number = 0x1792;
readonly name: string = 'MissingCollectionMintAccount';
constructor() {
super('Missing collection mint account');
if (typeof Error.captureStackTrace === 'function') {
Error.captureStackTrace(this, MissingCollectionMintAccountError);
}
}
}

createErrorFromCodeLookup.set(0x1792, () => new MissingCollectionMintAccountError());
createErrorFromNameLookup.set(
'MissingCollectionMintAccount',
() => new MissingCollectionMintAccountError(),
);

/**
* MissingCollectionMetadataAccount: 'Missing collection metadata account'
*
* @category Errors
* @category generated
*/
export class MissingCollectionMetadataAccountError extends Error {
readonly code: number = 0x1793;
readonly name: string = 'MissingCollectionMetadataAccount';
constructor() {
super('Missing collection metadata account');
if (typeof Error.captureStackTrace === 'function') {
Error.captureStackTrace(this, MissingCollectionMetadataAccountError);
}
}
}

createErrorFromCodeLookup.set(0x1793, () => new MissingCollectionMetadataAccountError());
createErrorFromNameLookup.set(
'MissingCollectionMetadataAccount',
() => new MissingCollectionMetadataAccountError(),
);

/**
* CollectionMismatch: 'Collection mismatch'
*
* @category Errors
* @category generated
*/
export class CollectionMismatchError extends Error {
readonly code: number = 0x1794;
readonly name: string = 'CollectionMismatch';
constructor() {
super('Collection mismatch');
if (typeof Error.captureStackTrace === 'function') {
Error.captureStackTrace(this, CollectionMismatchError);
}
}
}

createErrorFromCodeLookup.set(0x1794, () => new CollectionMismatchError());
createErrorFromNameLookup.set('CollectionMismatch', () => new CollectionMismatchError());

/**
* MetadataImmutable: 'Metadata not mutable'
*
* @category Errors
* @category generated
*/
export class MetadataImmutableError extends Error {
readonly code: number = 0x1795;
readonly name: string = 'MetadataImmutable';
constructor() {
super('Metadata not mutable');
if (typeof Error.captureStackTrace === 'function') {
Error.captureStackTrace(this, MetadataImmutableError);
}
}
}

createErrorFromCodeLookup.set(0x1795, () => new MetadataImmutableError());
createErrorFromNameLookup.set('MetadataImmutable', () => new MetadataImmutableError());

/**
* PrimarySaleCanOnlyBeFlippedToTrue: 'Can only update primary sale to true'
*
* @category Errors
* @category generated
*/
export class PrimarySaleCanOnlyBeFlippedToTrueError extends Error {
readonly code: number = 0x1796;
readonly name: string = 'PrimarySaleCanOnlyBeFlippedToTrue';
constructor() {
super('Can only update primary sale to true');
if (typeof Error.captureStackTrace === 'function') {
Error.captureStackTrace(this, PrimarySaleCanOnlyBeFlippedToTrueError);
}
}
}

createErrorFromCodeLookup.set(0x1796, () => new PrimarySaleCanOnlyBeFlippedToTrueError());
createErrorFromNameLookup.set(
'PrimarySaleCanOnlyBeFlippedToTrue',
() => new PrimarySaleCanOnlyBeFlippedToTrueError(),
);

/**
* CreatorDidNotUnverify: 'Creator did not unverify the metadata'
*
* @category Errors
* @category generated
*/
export class CreatorDidNotUnverifyError extends Error {
readonly code: number = 0x1797;
readonly name: string = 'CreatorDidNotUnverify';
constructor() {
super('Creator did not unverify the metadata');
if (typeof Error.captureStackTrace === 'function') {
Error.captureStackTrace(this, CreatorDidNotUnverifyError);
}
}
}

createErrorFromCodeLookup.set(0x1797, () => new CreatorDidNotUnverifyError());
createErrorFromNameLookup.set('CreatorDidNotUnverify', () => new CreatorDidNotUnverifyError());

/**
* Attempts to resolve a custom program error from the provided error code.
* @category Errors
Expand Down
1 change: 1 addition & 0 deletions clients/js-solita/src/generated/instructions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export * from './setTreeDelegate';
export * from './transfer';
export * from './unverifyCollection';
export * from './unverifyCreator';
export * from './updateMetadata';
export * from './verifyCollection';
export * from './verifyCreator';
185 changes: 185 additions & 0 deletions clients/js-solita/src/generated/instructions/updateMetadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/**
* This code was GENERATED using the solita package.
* Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality.
*
* See: https://github.com/metaplex-foundation/solita
*/

import * as beet from '@metaplex-foundation/beet';
import * as web3 from '@solana/web3.js';
import { MetadataArgs, metadataArgsBeet } from '../types/MetadataArgs';
import { UpdateArgs, updateArgsBeet } from '../types/UpdateArgs';

/**
* @category Instructions
* @category UpdateMetadata
* @category generated
*/
export type UpdateMetadataInstructionArgs = {
root: number[] /* size: 32 */;
nonce: beet.bignum;
index: number;
currentMetadata: MetadataArgs;
updateArgs: UpdateArgs;
};
/**
* @category Instructions
* @category UpdateMetadata
* @category generated
*/
export const updateMetadataStruct = new beet.FixableBeetArgsStruct<
UpdateMetadataInstructionArgs & {
instructionDiscriminator: number[] /* size: 8 */;
}
>(
[
['instructionDiscriminator', beet.uniformFixedSizeArray(beet.u8, 8)],
['root', beet.uniformFixedSizeArray(beet.u8, 32)],
['nonce', beet.u64],
['index', beet.u32],
['currentMetadata', metadataArgsBeet],
['updateArgs', updateArgsBeet],
],
'UpdateMetadataInstructionArgs',
);
/**
* Accounts required by the _updateMetadata_ instruction
*
* @property [] treeAuthority
* @property [**signer**] authority
* @property [] collectionMint (optional)
* @property [] collectionMetadata (optional)
* @property [] collectionAuthorityRecordPda (optional)
* @property [] leafOwner
* @property [] leafDelegate
* @property [**signer**] payer
* @property [_writable_] merkleTree
* @property [] logWrapper
* @property [] compressionProgram
* @property [] tokenMetadataProgram
* @category Instructions
* @category UpdateMetadata
* @category generated
*/
export type UpdateMetadataInstructionAccounts = {
treeAuthority: web3.PublicKey;
authority: web3.PublicKey;
collectionMint?: web3.PublicKey;
collectionMetadata?: web3.PublicKey;
collectionAuthorityRecordPda?: web3.PublicKey;
leafOwner: web3.PublicKey;
leafDelegate: web3.PublicKey;
payer: web3.PublicKey;
merkleTree: web3.PublicKey;
logWrapper: web3.PublicKey;
compressionProgram: web3.PublicKey;
tokenMetadataProgram: web3.PublicKey;
systemProgram?: web3.PublicKey;
anchorRemainingAccounts?: web3.AccountMeta[];
};

export const updateMetadataInstructionDiscriminator = [170, 182, 43, 239, 97, 78, 225, 186];

/**
* Creates a _UpdateMetadata_ instruction.
*
* Optional accounts that are not provided default to the program ID since
* this was indicated in the IDL from which this instruction was generated.
*
* @param accounts that will be accessed while the instruction is processed
* @param args to provide as instruction data to the program
*
* @category Instructions
* @category UpdateMetadata
* @category generated
*/
export function createUpdateMetadataInstruction(
accounts: UpdateMetadataInstructionAccounts,
args: UpdateMetadataInstructionArgs,
programId = new web3.PublicKey('BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY'),
) {
const [data] = updateMetadataStruct.serialize({
instructionDiscriminator: updateMetadataInstructionDiscriminator,
...args,
});
const keys: web3.AccountMeta[] = [
{
pubkey: accounts.treeAuthority,
isWritable: false,
isSigner: false,
},
{
pubkey: accounts.authority,
isWritable: false,
isSigner: true,
},
{
pubkey: accounts.collectionMint ?? programId,
isWritable: false,
isSigner: false,
},
{
pubkey: accounts.collectionMetadata ?? programId,
isWritable: false,
isSigner: false,
},
{
pubkey: accounts.collectionAuthorityRecordPda ?? programId,
isWritable: false,
isSigner: false,
},
{
pubkey: accounts.leafOwner,
isWritable: false,
isSigner: false,
},
{
pubkey: accounts.leafDelegate,
isWritable: false,
isSigner: false,
},
{
pubkey: accounts.payer,
isWritable: false,
isSigner: true,
},
{
pubkey: accounts.merkleTree,
isWritable: true,
isSigner: false,
},
{
pubkey: accounts.logWrapper,
isWritable: false,
isSigner: false,
},
{
pubkey: accounts.compressionProgram,
isWritable: false,
isSigner: false,
},
{
pubkey: accounts.tokenMetadataProgram,
isWritable: false,
isSigner: false,
},
{
pubkey: accounts.systemProgram ?? web3.SystemProgram.programId,
isWritable: false,
isSigner: false,
},
];

if (accounts.anchorRemainingAccounts != null) {
for (const acc of accounts.anchorRemainingAccounts) {
keys.push(acc);
}
}

const ix = new web3.TransactionInstruction({
programId,
keys,
data,
});
return ix;
}
Loading

0 comments on commit 1b119a8

Please sign in to comment.