Skip to content

Commit

Permalink
fix external plugin offsets, better types, new tests (#109)
Browse files Browse the repository at this point in the history
* Adding anchor types.

* Update.

* removed audit warning (#108)

* better types, new test

* Updating Kinobi dependency.

* Fixing kinobi reference.

* Bumping Kinobi version and fixing clients.

* Fixing mpl-utils version.

* Immutability plugins (#96)

* Add ImmutableMetadata && AddBlocker plugins

* Update autogenerated parts

* add tests

* change the order of enums

* update generated part

* added tests for ensuring that UA is the only one who can add the plugin

* added tests for ensuring that UA is the only one who can add the plugin for collection and nested plugins

* update tests

* add audit details to readme (#103)

* removed audit warning (#108)

* regenerated clients

* updated tests

* updated rust clients

* chore: Release mpl-core version 0.6.0

* Modify `update` and `update_plugin` to move external plugin offsets (#112)

Notes
Also combine asset and collection update functions to use the same processors.
Also fix offset calculations when updating external plugins (added test for this case).
More advanced refactor: Combine plugin updating into single utility function #113
Note this PR is built upon #109 so that it can be tested with the new tests from that branch.

* Deploy JS client v0.4.7

* update ava version, allow assertions on external plugins, check oracles in oracle tests

* minor add plugin interface change

* add additional test assert, formatting

---------

Co-authored-by: blockiosaurus <[email protected]>
Co-authored-by: Tony Boyle <[email protected]>
Co-authored-by: Kyrylo Stepanov <[email protected]>
Co-authored-by: blockiosaurus <[email protected]>
Co-authored-by: blockiosaurus <[email protected]>
Co-authored-by: Michael Danenberg <[email protected]>
  • Loading branch information
7 people authored May 8, 2024
1 parent 9443626 commit 204e2f1
Show file tree
Hide file tree
Showing 132 changed files with 3,539 additions and 1,494 deletions.
1,154 changes: 700 additions & 454 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
# Mpl Core

> [!WARNING]
> Metaplex Core is currently undergoing audit. Use in production at your own risk.
Digital Assets

## Documentation
Expand Down
258 changes: 133 additions & 125 deletions clients/js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,138 +38,146 @@ A Umi-compatible JavaScript library for the project.
4. Examples
```ts
// Create an asset
const assetAddress = generateSigner(umi);
const owner = generateSigner(umi);

await createV1(umi, {
name: 'Test Asset',
uri: 'https://example.com/asset.json',
asset: assetAddress,
owner: owner.publicKey, // optional, will default to payer
}).sendAndConfirm(umi);

// Create a collection
const collectionUpdateAuthority = generateSigner(umi);
const collectionAddress = generateSigner(umi);
await createCollectionV1(umi, {
name: 'Test Collection',
uri: 'https://example.com/collection.json',
collection: collectionAddress,
updateAuthority: collectionUpdateAuthority.publicKey, // optional, defaults to payer
}).sendAndConfirm(umi);

// Create an asset in a collection, the authority must be the updateAuthority of the collection
await createV1(umi, {
name: 'Test Asset',
uri: 'https://example.com/asset.json',
asset: assetAddress,
collection: collectionAddress.publicKey,
authority: collectionUpdateAuthority, // optional, defaults to payer
}).sendAndConfirm(umi);

// Transfer an asset
const recipient = generateSigner(umi);
await transferV1(umi, {
asset: assetAddress.publicKey,
newOwner: recipient.publicKey,
}).sendAndConfirm(umi);

// Transfer an asset in a collection
await transferV1(umi, {
asset: assetAddress.publicKey,
newOwner: recipient.publicKey,
collection: collectionAddress.publicKey,
}).sendAndConfirm(umi);

// Fetch an asset
const asset = await fetchAssetV1(umi, assetAddress.publicKey);

// GPA fetch assets by owner
const assetsByOwner = await getAssetV1GpaBuilder(umi)
.whereField('key', Key.AssetV1)
.whereField('owner', owner.publicKey)
.getDeserialized();

// GPA fetch assets by collection
const assetsByCollection = await getAssetV1GpaBuilder(umi)
.whereField('key', Key.AssetV1)
.whereField(
'updateAuthority',
updateAuthority('Collection', [collectionAddress.publicKey])
)
.getDeserialized();

// DAS API (RPC based indexing) fetch assets by owner/collection
// Coming soon
const assetAddress = generateSigner(umi);
const owner = generateSigner(umi);

await create(umi, {
name: 'Test Asset',
uri: 'https://example.com/asset.json',
asset: assetAddress,
owner: owner.publicKey, // optional, will default to payer
}).sendAndConfirm(umi);

// Fetch an asset
const asset = await fetchAssetV1(umi, assetAddress.publicKey);

// Create a collection
const collectionUpdateAuthority = generateSigner(umi);
const collectionAddress = generateSigner(umi);
await createCollection(umi, {
name: 'Test Collection',
uri: 'https://example.com/collection.json',
collection: collectionAddress,
updateAuthority: collectionUpdateAuthority.publicKey, // optional, defaults to payer
}).sendAndConfirm(umi);

// Fetch a collection
const collection = await fetchCollectionV1(umi, collectionAddress.publicKey);

// Create an asset in a collection, the authority must be the updateAuthority of the collection
await create(umi, {
name: 'Test Asset',
uri: 'https://example.com/asset.json',
asset: assetAddress,
collection,
authority: collectionUpdateAuthority, // optional, defaults to payer
}).sendAndConfirm(umi);

// Transfer an asset
const recipient = generateSigner(umi);
await transfer(umi, {
asset,
newOwner: recipient.publicKey,
}).sendAndConfirm(umi);

// Transfer an asset in a collection
await transfer(umi, {
asset,
newOwner: recipient.publicKey,
collection,
}).sendAndConfirm(umi);

// GPA fetch assets by owner
const assetsByOwner = await getAssetV1GpaBuilder(umi)
.whereField('key', Key.AssetV1)
.whereField('owner', owner.publicKey)
.getDeserialized();

// GPA fetch assets by collection
const assetsByCollection = await getAssetV1GpaBuilder(umi)
.whereField('key', Key.AssetV1)
.whereField(
'updateAuthority',
updateAuthority('Collection', [collectionAddress.publicKey])
)
.getDeserialized();

// DAS API (RPC based indexing) fetch assets by owner/collection
// Coming soon

```
5. Some advanced examples
```ts
// Freezing an asset
const assetAddress = generateSigner(umi);
const freezeDelegate = generateSigner(umi);

await addPluginV1(umi, {
asset: assetAddress.publicKey,
// adds the owner-managed freeze plugin to the asset
plugin: createPlugin({
type: 'FreezeDelegate',
data: {
frozen: true,
},
}),
const umi = await createUmi();

// Freezing an asset
const assetAddress = generateSigner(umi);
const freezeDelegate = generateSigner(umi);

await addPlugin(umi, {
asset: assetAddress.publicKey,
// adds the owner-managed freeze plugin to the asset
plugin: {
type: 'FreezeDelegate',
frozen: true,

// Optionally set the authority to a delegate who can unfreeze. If unset, this will be the Owner
// This is functionally the same as calling addPlugin and approvePluginAuthority separately.
// Freezing with a delegate is commonly used for escrowless staking programs.
initAuthority: addressPluginAuthority(freezeDelegate.publicKey),
}).sendAndConfirm(umi);

// Unfreezing an asset with a delegate
// Revoking an authority will revert the authority back to the owner for owner-managed plugins
await revokePluginAuthorityV1(umi, {
asset: assetAddress.publicKey,
pluginType: PluginType.FreezeDelegate,
authority: freezeDelegate,
}).sendAndConfirm(umi);

// Create a collection with royalties
const collectionAddress = generateSigner(umi);
const creator1 = generateSigner(umi);
const creator2 = generateSigner(umi);

await createCollectionV1(umi, {
name: 'Test Collection',
uri: 'https://example.com/collection.json',
collection: collectionAddress,
plugins: [
pluginAuthorityPair({
type: 'Royalties',
data: {
basisPoints: 500,
creators: [
{
address: creator1.publicKey,
percentage: 20,
},
{
address: creator2.publicKey,
percentage: 80,
},
],
ruleSet: ruleSet('None'), // Compatibility rule set
},
}),
],
}).sendAndConfirm(umi);

// Create an asset in a collection.
// Assets in a collection will inherit the collection's authority-managed plugins, in this case the royalties plugin
await createV1(umi, {
name: 'Test Asset',
uri: 'https://example.com/asset.json',
asset: assetAddress,
collection: collectionAddress.publicKey,
}).sendAndConfirm(umi);
authority: {
type: 'Address',
address: freezeDelegate.publicKey,
},
}
}).sendAndConfirm(umi);

// Unfreezing an asset with a delegate
// Revoking an authority will revert the authority back to the owner for owner-managed plugins
await revokePluginAuthority(umi, {
asset: assetAddress.publicKey,
plugin: {
type: 'FreezeDelegate',
},
authority: freezeDelegate,
}).sendAndConfirm(umi);

// Create a collection with royalties
const collectionAddress = generateSigner(umi);
const creator1 = generateSigner(umi);
const creator2 = generateSigner(umi);

await createCollection(umi, {
name: 'Test Collection',
uri: 'https://example.com/collection.json',
collection: collectionAddress,
plugins: [
{
type: 'Royalties',
basisPoints: 500,
creators: [
{
address: creator1.publicKey,
percentage: 20,
},
{
address: creator2.publicKey,
percentage: 80,
},
],
ruleSet: ruleSet('None'), // Compatibility rule set

},
],
}).sendAndConfirm(umi);

// Create an asset in a collection.
// Assets in a collection will inherit the collection's authority-managed plugins, in this case the royalties plugin
await create(umi, {
name: 'Test Asset',
uri: 'https://example.com/asset.json',
asset: assetAddress,
collection: await fetchCollectionV1(umi, collectionAddress.publicKey),
}).sendAndConfirm(umi);
```

You can learn more about this library's API by reading its generated [TypeDoc documentation](https://mpl-core-js-docs.vercel.app).
Expand Down
9 changes: 4 additions & 5 deletions clients/js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@metaplex-foundation/mpl-core",
"version": "0.4.6",
"version": "0.4.7",
"description": "Digital Assets",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
Expand All @@ -25,21 +25,20 @@
"repository": "https://github.com/metaplex-foundation/mpl-core.git",
"author": "Metaplex Maintainers <[email protected]>",
"license": "Apache-2.0",
"dependencies": {},
"peerDependencies": {
"@metaplex-foundation/umi": ">=0.8.2 < 1",
"@noble/hashes": "^1.3.1"
},
"devDependencies": {
"@metaplex-foundation/mpl-toolbox": "^0.8.0",
"@ava/typescript": "^3.0.1",
"@ava/typescript": "^5.0.0",
"@metaplex-foundation/mpl-core-oracle-example": "^0.0.1",
"@metaplex-foundation/mpl-toolbox": "^0.8.0",
"@metaplex-foundation/umi": "^0.8.10",
"@metaplex-foundation/umi-bundle-tests": "^0.8.10",
"@solana/web3.js": "^1.73.0",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.46.1",
"ava": "^5.1.0",
"ava": "^6.1.3",
"bs58": "5.0.0",
"eslint": "^8.0.1",
"eslint-config-airbnb-typescript": "^17.0.0",
Expand Down
Loading

0 comments on commit 204e2f1

Please sign in to comment.