Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin side effects with example. #221

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
language: "en-US"
early_access: false
reviews:
profile: "chill"
request_changes_workflow: false
high_level_summary: true
poem: true
review_status: true
collapse_walkthrough: false
path_instructions:
[
{
path: "programs/mpl-core/src/processor/*",
instructions: "Make sure the owner is checked on all accounts somehow",
},
{
path: "programs/mpl-core/*",
instructions: "Carefully consider performance implications and make sure there are no performance inefficiencies",
},
{
path: "**/*.rs",
instructions: "Make duplicated logic between the rust client and program are consistent",
},
]
auto_review:
enabled: true
drafts: false
chat:
auto_reply: true
1 change: 1 addition & 0 deletions clients/js/src/generated/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export * from './plugin';
export * from './pluginAuthorityPair';
export * from './pluginType';
export * from './registryRecord';
export * from './transferCount';
export * from './transferDelegate';
export * from './updateDelegate';
export * from './validationResult';
Expand Down
19 changes: 17 additions & 2 deletions clients/js/src/generated/types/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ import {
PermanentFreezeDelegateArgs,
PermanentTransferDelegate,
PermanentTransferDelegateArgs,
TransferCount,
TransferCountArgs,
TransferDelegate,
TransferDelegateArgs,
UpdateDelegate,
Expand All @@ -57,6 +59,7 @@ import {
getPermanentBurnDelegateSerializer,
getPermanentFreezeDelegateSerializer,
getPermanentTransferDelegateSerializer,
getTransferCountSerializer,
getTransferDelegateSerializer,
getUpdateDelegateSerializer,
getVerifiedCreatorsSerializer,
Expand All @@ -77,7 +80,8 @@ export type Plugin =
| { __kind: 'AddBlocker'; fields: [AddBlocker] }
| { __kind: 'ImmutableMetadata'; fields: [ImmutableMetadata] }
| { __kind: 'VerifiedCreators'; fields: [VerifiedCreators] }
| { __kind: 'Autograph'; fields: [Autograph] };
| { __kind: 'Autograph'; fields: [Autograph] }
| { __kind: 'TransferCount'; fields: [TransferCount] };

export type PluginArgs =
| { __kind: 'Royalties'; fields: [BaseRoyaltiesArgs] }
Expand All @@ -97,7 +101,8 @@ export type PluginArgs =
| { __kind: 'AddBlocker'; fields: [AddBlockerArgs] }
| { __kind: 'ImmutableMetadata'; fields: [ImmutableMetadataArgs] }
| { __kind: 'VerifiedCreators'; fields: [VerifiedCreatorsArgs] }
| { __kind: 'Autograph'; fields: [AutographArgs] };
| { __kind: 'Autograph'; fields: [AutographArgs] }
| { __kind: 'TransferCount'; fields: [TransferCountArgs] };

export function getPluginSerializer(): Serializer<PluginArgs, Plugin> {
return dataEnum<Plugin>(
Expand Down Expand Up @@ -192,6 +197,12 @@ export function getPluginSerializer(): Serializer<PluginArgs, Plugin> {
['fields', tuple([getAutographSerializer()])],
]),
],
[
'TransferCount',
struct<GetDataEnumKindContent<Plugin, 'TransferCount'>>([
['fields', tuple([getTransferCountSerializer()])],
]),
],
],
{ description: 'Plugin' }
) as Serializer<PluginArgs, Plugin>;
Expand Down Expand Up @@ -261,6 +272,10 @@ export function plugin(
kind: 'Autograph',
data: GetDataEnumKindContent<PluginArgs, 'Autograph'>['fields']
): GetDataEnumKind<PluginArgs, 'Autograph'>;
export function plugin(
kind: 'TransferCount',
data: GetDataEnumKindContent<PluginArgs, 'TransferCount'>['fields']
): GetDataEnumKind<PluginArgs, 'TransferCount'>;
export function plugin<K extends PluginArgs['__kind']>(
kind: K,
data?: any
Expand Down
1 change: 1 addition & 0 deletions clients/js/src/generated/types/pluginType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export enum PluginType {
ImmutableMetadata,
VerifiedCreators,
Autograph,
TransferCount,
}

export type PluginTypeArgs = PluginType;
Expand Down
22 changes: 22 additions & 0 deletions clients/js/src/generated/types/transferCount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* This code was AUTOGENERATED using the kinobi library.
* Please DO NOT EDIT THIS FILE, instead use visitors
* to add features, then rerun kinobi to update it.
*
* @see https://github.com/metaplex-foundation/kinobi
*/

import { Serializer, struct, u64 } from '@metaplex-foundation/umi/serializers';

export type TransferCount = { count: bigint };

export type TransferCountArgs = { count: number | bigint };

export function getTransferCountSerializer(): Serializer<
TransferCountArgs,
TransferCount
> {
return struct<TransferCount>([['count', u64()]], {
description: 'TransferCount',
}) as Serializer<TransferCountArgs, TransferCount>;
}
13 changes: 11 additions & 2 deletions clients/js/src/plugins/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import {
VerifiedCreatorsArgs,
Autograph,
VerifiedCreators,
TransferCount,
TransferCountArgs,
} from '../generated';
import { RoyaltiesArgs, RoyaltiesPlugin } from './royalties';
import { PluginAuthority } from './pluginAuthority';
Expand Down Expand Up @@ -88,6 +90,9 @@ export type CreatePluginArgs =
}
| {
type: 'AddBlocker';
}
| {
type: 'TransferCount';
};

export type AuthorityArgsV2 = {
Expand Down Expand Up @@ -143,7 +148,10 @@ export type AuthorityManagedPluginArgsV2 =
}
| ({
type: 'VerifiedCreators';
} & VerifiedCreatorsArgs);
} & VerifiedCreatorsArgs)
| ({
type: 'TransferCount';
} & TransferCountArgs);

export type AssetAddablePluginArgsV2 =
| OwnerManagedPluginArgsV2
Expand Down Expand Up @@ -181,7 +189,7 @@ export type AddBlockerPlugin = BasePlugin & AddBlocker;
export type ImmutableMetadataPlugin = BasePlugin & ImmutableMetadata;
export type VerifiedCreatorsPlugin = BasePlugin & VerifiedCreators;
export type AutographPlugin = BasePlugin & Autograph;

export type TransferCountPlugin = BasePlugin & TransferCount;
export type CommonPluginsList = {
attributes?: AttributesPlugin;
royalties?: RoyaltiesPlugin;
Expand All @@ -193,6 +201,7 @@ export type CommonPluginsList = {
immutableMetadata?: ImmutableMetadataPlugin;
autograph?: AutographPlugin;
verifiedCreators?: VerifiedCreatorsPlugin;
transferCount?: TransferCountPlugin;
};

export type AssetPluginsList = {
Expand Down
40 changes: 40 additions & 0 deletions clients/js/test/plugins/asset/transferCount.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import test from 'ava';
import { generateSigner } from '@metaplex-foundation/umi';
import { transferV1 } from '../../../src';
import { assertAsset, createUmi } from '../../_setupRaw';
import { createAsset } from '../../_setupSdk';

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

const asset = await createAsset(umi, {
plugins: [
{
type: 'TransferCount',
count: 0,
},
],
});
await assertAsset(t, umi, {
asset: asset.publicKey,
owner: umi.identity.publicKey,
updateAuthority: { type: 'Address', address: umi.identity.publicKey },
transferCount: { count: 0n, authority: { type: 'UpdateAuthority' } },
});

const tx = await transferV1(umi, {
asset: asset.publicKey,
newOwner: newOwner.publicKey,
}).sendAndConfirm(umi);

console.log((await umi.rpc.getTransaction(tx.signature))?.meta?.logs);

await assertAsset(t, umi, {
asset: asset.publicKey,
owner: newOwner.publicKey,
updateAuthority: { type: 'Address', address: umi.identity.publicKey },
transferCount: { count: 1n, authority: { type: 'UpdateAuthority' } },
});
});
2 changes: 2 additions & 0 deletions clients/rust/src/generated/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub(crate) mod r#registry_record;
pub(crate) mod r#royalties;
pub(crate) mod r#rule_set;
pub(crate) mod r#seed;
pub(crate) mod r#transfer_count;
pub(crate) mod r#transfer_delegate;
pub(crate) mod r#update_authority;
pub(crate) mod r#update_delegate;
Expand Down Expand Up @@ -129,6 +130,7 @@ pub use self::r#registry_record::*;
pub use self::r#royalties::*;
pub use self::r#rule_set::*;
pub use self::r#seed::*;
pub use self::r#transfer_count::*;
pub use self::r#transfer_delegate::*;
pub use self::r#update_authority::*;
pub use self::r#update_delegate::*;
Expand Down
2 changes: 2 additions & 0 deletions clients/rust/src/generated/types/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::generated::types::PermanentBurnDelegate;
use crate::generated::types::PermanentFreezeDelegate;
use crate::generated::types::PermanentTransferDelegate;
use crate::generated::types::Royalties;
use crate::generated::types::TransferCount;
use crate::generated::types::TransferDelegate;
use crate::generated::types::UpdateDelegate;
use crate::generated::types::VerifiedCreators;
Expand Down Expand Up @@ -45,4 +46,5 @@ pub enum Plugin {
ImmutableMetadata(ImmutableMetadata),
VerifiedCreators(VerifiedCreators),
Autograph(Autograph),
TransferCount(TransferCount),
}
1 change: 1 addition & 0 deletions clients/rust/src/generated/types/plugin_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ pub enum PluginType {
ImmutableMetadata,
VerifiedCreators,
Autograph,
TransferCount,
}
19 changes: 19 additions & 0 deletions clients/rust/src/generated/types/transfer_count.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//! This code was AUTOGENERATED using the kinobi library.
//! Please DO NOT EDIT THIS FILE, instead use visitors
//! to add features, then rerun kinobi to update it.
//!
//! [https://github.com/metaplex-foundation/kinobi]
//!

#[cfg(feature = "anchor")]
use anchor_lang::prelude::{AnchorDeserialize, AnchorSerialize};
#[cfg(not(feature = "anchor"))]
use borsh::{BorshDeserialize, BorshSerialize};

#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(not(feature = "anchor"), derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "anchor", derive(AnchorSerialize, AnchorDeserialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct TransferCount {
pub count: u64,
}
23 changes: 23 additions & 0 deletions idls/mpl_core.json
Original file line number Diff line number Diff line change
Expand Up @@ -2942,6 +2942,18 @@
]
}
},
{
"name": "TransferCount",
"type": {
"kind": "struct",
"fields": [
{
"name": "count",
"type": "u64"
}
]
}
},
{
"name": "UpdateDelegate",
"type": {
Expand Down Expand Up @@ -3984,6 +3996,14 @@
"defined": "Autograph"
}
]
},
{
"name": "TransferCount",
"fields": [
{
"defined": "TransferCount"
}
]
}
]
}
Expand Down Expand Up @@ -4037,6 +4057,9 @@
},
{
"name": "Autograph"
},
{
"name": "TransferCount"
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod attributes;
mod immutable_metadata;
mod master_edition;
mod royalties;
mod transfer_count;
mod update_delegate;
mod verified_creators;

Expand All @@ -11,5 +12,6 @@ pub use attributes::*;
pub use immutable_metadata::*;
pub use master_edition::*;
pub use royalties::*;
pub use transfer_count::*;
pub use update_delegate::*;
pub use verified_creators::*;
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use crate::{
plugins::{Plugin, PluginValidation},
state::DataBlob,
};
use borsh::{BorshDeserialize, BorshSerialize};

/// The TransferCount plugin tracks the number of times an asset has been transferred.
#[repr(C)]
#[derive(Clone, BorshSerialize, BorshDeserialize, Debug, PartialEq, Eq, Default)]
pub struct TransferCount {
/// The number of times the asset has been transferred.
pub count: u64,
}

impl TransferCount {
const BASE_LEN: usize = 8; // The size of u64

/// Initialize the TransferCount plugin with a count of 0.
pub fn new() -> Self {
Self::default()
}
}

impl DataBlob for TransferCount {
fn len(&self) -> usize {
Self::BASE_LEN
}
}

impl PluginValidation for TransferCount {
fn side_effects_transfer(
&self,
_ctx: &crate::plugins::PluginSideEffectContext,
) -> Result<Plugin, solana_program::program_error::ProgramError> {
Ok(Plugin::TransferCount(TransferCount {
count: self.count + 1,
}))
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_transfer_count_len() {
let transfer_count = TransferCount { count: 0 };
let serialized = transfer_count.try_to_vec().unwrap();
assert_eq!(serialized.len(), transfer_count.len());
}

#[test]
fn test_transfer_count_default_len() {
let transfer_count = TransferCount::new();
let serialized = transfer_count.try_to_vec().unwrap();
assert_eq!(serialized.len(), transfer_count.len());
}
}
Loading
Loading