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

Moving the wallet 2 wallet check to auth rules. #89

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions clients/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
},
"devDependencies": {
"@ava/typescript": "^3.0.1",
"@metaplex-foundation/mpl-token-auth-rules": "^3.0.2",
"@metaplex-foundation/umi": "^0.8.2",
"@metaplex-foundation/umi-bundle-tests": "^0.8.2",
"@solana/web3.js": "^1.73.0",
Expand Down
21 changes: 21 additions & 0 deletions clients/js/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

125 changes: 124 additions & 1 deletion clients/js/test/transferV1.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { findAssociatedTokenPda } from '@metaplex-foundation/mpl-toolbox';
import { generateSigner, publicKey } from '@metaplex-foundation/umi';
import { RuleSetRevisionV2, findRuleSetPda, createOrUpdateV1 } from '@metaplex-foundation/mpl-token-auth-rules';
import { generateSigner, publicKey, sol, some } from '@metaplex-foundation/umi';
import test from 'ava';
import {
DigitalAssetWithToken,
Expand Down Expand Up @@ -91,6 +92,128 @@ test('it can transfer a ProgrammableNonFungible', async (t) => {
});
});

test('it can transfer a ProgrammableNonFungible between two wallets', async (t) => {
// Given a ProgrammableNonFungible that belongs to owner A.
const umi = await createUmi();
const ownerA = generateSigner(umi);
await umi.rpc.airdrop(ownerA.publicKey, sol(10));

const ruleSetName = 'transfer_test';
const revision: RuleSetRevisionV2 = {
libVersion: 2,
name: ruleSetName,
owner: ownerA.publicKey,
operations: JSON.parse('{"Transfer:Owner": {"type": "IsWallet", "field": "Destination"}}')
};

const ruleSetPda = findRuleSetPda(umi, { owner: ownerA.publicKey, name: ruleSetName });
await createOrUpdateV1(umi, {
payer: ownerA,
ruleSetPda,
ruleSetRevision: some(revision),
}).sendAndConfirm(umi);

const { publicKey: mint } = await createDigitalAssetWithToken(umi, {
tokenOwner: ownerA.publicKey,
tokenStandard: TokenStandard.ProgrammableNonFungible,
ruleSet: ruleSetPda[0],
});

// When we transfer the asset to owner B.
const ownerB = generateSigner(umi).publicKey;

await transferV1(umi, {
mint,
authority: ownerA,
tokenOwner: ownerA.publicKey,
destinationOwner: ownerB,
tokenStandard: TokenStandard.ProgrammableNonFungible,
authorizationRules: ruleSetPda,
}).sendAndConfirm(umi);

// Then the asset is now owned by owner B.
const da = await fetchDigitalAssetWithAssociatedToken(umi, mint, ownerB);
t.like(da, <DigitalAssetWithToken>{
mint: {
publicKey: publicKey(mint),
supply: 1n,
},
token: {
publicKey: findAssociatedTokenPda(umi, {
mint,
owner: ownerB,
})[0],
owner: ownerB,
amount: 1n,
},
tokenRecord: {
state: TokenState.Unlocked,
},
});
});

test('it can\'t transfer a ProgrammableNonFungible to a program - owned wallet with isWallet', async (t) => {
// Given a ProgrammableNonFungible that belongs to owner A.
const umi = await createUmi();
const ownerA = generateSigner(umi);
await umi.rpc.airdrop(ownerA.publicKey, sol(10));

const ruleSetName = 'transfer_test';
const revision: RuleSetRevisionV2 = {
libVersion: 2,
name: ruleSetName,
owner: ownerA.publicKey,
operations: JSON.parse('{"Transfer:Owner": {"type": "IsWallet", "field": "Destination"}}')
};

const ruleSetPda = findRuleSetPda(umi, { owner: ownerA.publicKey, name: ruleSetName });
await createOrUpdateV1(umi, {
payer: ownerA,
ruleSetPda,
ruleSetRevision: some(revision),
}).sendAndConfirm(umi);

const { publicKey: mint } = await createDigitalAssetWithToken(umi, {
tokenOwner: ownerA.publicKey,
tokenStandard: TokenStandard.ProgrammableNonFungible,
ruleSet: ruleSetPda[0],
});

// When we transfer the asset to owner B.
const ownerB = generateSigner(umi).publicKey;

const promise = transferV1(umi, {
mint,
authority: ownerA,
tokenOwner: ownerA.publicKey,
destinationOwner: mint,
tokenStandard: TokenStandard.ProgrammableNonFungible,
authorizationRules: ruleSetPda,
}).sendAndConfirm(umi);

await t.throwsAsync(promise, { name: 'AuthorizationTokenAccountOwnerMismatch' });

// Then the asset is now owned by owner B.
const da = await fetchDigitalAssetWithAssociatedToken(umi, mint, ownerA.publicKey);
t.like(da, <DigitalAssetWithToken>{
mint: {
publicKey: publicKey(mint),
supply: 1n,
},
token: {
publicKey: findAssociatedTokenPda(umi, {
mint,
owner: ownerA.publicKey,
})[0],
owner: ownerA.publicKey,
amount: 1n,
},
tokenRecord: {
state: TokenState.Unlocked,
},
});
});

NON_EDITION_NON_FUNGIBLE_STANDARDS.forEach((tokenStandard) => {
test(`it cannot transfer a ${tokenStandard} with an amount of 0`, async (t) => {
// Given a NonFungible that is owned by owner A.
Expand Down
12 changes: 0 additions & 12 deletions clients/rust/src/generated/accounts/collection_authority_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,6 @@ pub struct CollectionAuthorityRecord {
}

impl CollectionAuthorityRecord {
/// Prefix values used to generate a PDA for this account.
///
/// Values are positional and appear in the following order:
///
/// 0. `CollectionAuthorityRecord::PREFIX.0`
/// 1. `crate::MPL_TOKEN_METADATA_ID`
/// 2. mint (`Pubkey`)
/// 3. `CollectionAuthorityRecord::PREFIX.1`
/// 4. collection_authority (`Pubkey`)
pub const PREFIX: (&'static [u8], &'static [u8]) =
("metadata".as_bytes(), "collection_authority".as_bytes());

pub fn create_pda(
mint: Pubkey,
collection_authority: Pubkey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,6 @@ pub struct DeprecatedMasterEditionV1 {
}

impl DeprecatedMasterEditionV1 {
/// Prefix values used to generate a PDA for this account.
///
/// Values are positional and appear in the following order:
///
/// 0. `DeprecatedMasterEditionV1::PREFIX.0`
/// 1. `crate::MPL_TOKEN_METADATA_ID`
/// 2. mint (`Pubkey`)
/// 3. `DeprecatedMasterEditionV1::PREFIX.1`
pub const PREFIX: (&'static [u8], &'static [u8]) =
("metadata".as_bytes(), "edition".as_bytes());

pub fn create_pda(
mint: Pubkey,
bump: u8,
Expand Down
11 changes: 0 additions & 11 deletions clients/rust/src/generated/accounts/edition_marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,6 @@ pub struct EditionMarker {

impl EditionMarker {
pub const LEN: usize = 32;
/// Prefix values used to generate a PDA for this account.
///
/// Values are positional and appear in the following order:
///
/// 0. `EditionMarker::PREFIX.0`
/// 1. `crate::MPL_TOKEN_METADATA_ID`
/// 2. mint (`Pubkey`)
/// 3. `EditionMarker::PREFIX.1`
/// 4. edition_marker (`&str`)
pub const PREFIX: (&'static [u8], &'static [u8]) =
("metadata".as_bytes(), "edition".as_bytes());

pub fn create_pda(
mint: Pubkey,
Expand Down
15 changes: 0 additions & 15 deletions clients/rust/src/generated/accounts/edition_marker_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,6 @@ pub struct EditionMarkerV2 {
}

impl EditionMarkerV2 {
/// Prefix values used to generate a PDA for this account.
///
/// Values are positional and appear in the following order:
///
/// 0. `EditionMarkerV2::PREFIX.0`
/// 1. `crate::MPL_TOKEN_METADATA_ID`
/// 2. mint (`Pubkey`)
/// 3. `EditionMarkerV2::PREFIX.1`
/// 4. `EditionMarkerV2::PREFIX.2`
pub const PREFIX: (&'static [u8], &'static [u8], &'static [u8]) = (
"metadata".as_bytes(),
"edition".as_bytes(),
"marker".as_bytes(),
);

pub fn create_pda(
mint: Pubkey,
bump: u8,
Expand Down
11 changes: 0 additions & 11 deletions clients/rust/src/generated/accounts/master_edition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,6 @@ pub struct MasterEdition {
}

impl MasterEdition {
/// Prefix values used to generate a PDA for this account.
///
/// Values are positional and appear in the following order:
///
/// 0. `MasterEdition::PREFIX.0`
/// 1. `crate::MPL_TOKEN_METADATA_ID`
/// 2. mint (`Pubkey`)
/// 3. `MasterEdition::PREFIX.1`
pub const PREFIX: (&'static [u8], &'static [u8]) =
("metadata".as_bytes(), "edition".as_bytes());

pub fn create_pda(
mint: Pubkey,
bump: u8,
Expand Down
9 changes: 0 additions & 9 deletions clients/rust/src/generated/accounts/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,6 @@ pub struct Metadata {
}

impl Metadata {
/// Prefix values used to generate a PDA for this account.
///
/// Values are positional and appear in the following order:
///
/// 0. `Metadata::PREFIX`
/// 1. `crate::MPL_TOKEN_METADATA_ID`
/// 2. mint (`Pubkey`)
pub const PREFIX: &'static [u8] = "metadata".as_bytes();

pub fn create_pda(
mint: Pubkey,
bump: u8,
Expand Down
11 changes: 0 additions & 11 deletions clients/rust/src/generated/accounts/metadata_delegate_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,6 @@ pub struct MetadataDelegateRecord {

impl MetadataDelegateRecord {
pub const LEN: usize = 98;
/// Prefix values used to generate a PDA for this account.
///
/// Values are positional and appear in the following order:
///
/// 0. `MetadataDelegateRecord::PREFIX`
/// 1. `crate::MPL_TOKEN_METADATA_ID`
/// 2. mint (`Pubkey`)
/// 3. delegate_role (`MetadataDelegateRoleSeed`)
/// 4. update_authority (`Pubkey`)
/// 5. delegate (`Pubkey`)
pub const PREFIX: &'static [u8] = "metadata".as_bytes();

pub fn create_pda(
mint: Pubkey,
Expand Down
44 changes: 22 additions & 22 deletions clients/rust/src/generated/accounts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@
//! [https://github.com/metaplex-foundation/kinobi]
//!

pub(crate) mod r#collection_authority_record;
pub(crate) mod r#deprecated_master_edition_v1;
pub(crate) mod r#edition;
pub(crate) mod r#edition_marker;
pub(crate) mod r#edition_marker_v2;
pub(crate) mod r#master_edition;
pub(crate) mod r#metadata;
pub(crate) mod r#metadata_delegate_record;
pub(crate) mod r#token_owned_escrow;
pub(crate) mod r#token_record;
pub(crate) mod r#use_authority_record;
pub(crate) mod collection_authority_record;
pub(crate) mod deprecated_master_edition_v1;
pub(crate) mod edition;
pub(crate) mod edition_marker;
pub(crate) mod edition_marker_v2;
pub(crate) mod master_edition;
pub(crate) mod metadata;
pub(crate) mod metadata_delegate_record;
pub(crate) mod token_owned_escrow;
pub(crate) mod token_record;
pub(crate) mod use_authority_record;

pub use self::r#collection_authority_record::*;
pub use self::r#deprecated_master_edition_v1::*;
pub use self::r#edition::*;
pub use self::r#edition_marker::*;
pub use self::r#edition_marker_v2::*;
pub use self::r#master_edition::*;
pub use self::r#metadata::*;
pub use self::r#metadata_delegate_record::*;
pub use self::r#token_owned_escrow::*;
pub use self::r#token_record::*;
pub use self::r#use_authority_record::*;
pub use self::collection_authority_record::*;
pub use self::deprecated_master_edition_v1::*;
pub use self::edition::*;
pub use self::edition_marker::*;
pub use self::edition_marker_v2::*;
pub use self::master_edition::*;
pub use self::metadata::*;
pub use self::metadata_delegate_record::*;
pub use self::token_owned_escrow::*;
pub use self::token_record::*;
pub use self::use_authority_record::*;
11 changes: 0 additions & 11 deletions clients/rust/src/generated/accounts/token_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,6 @@ pub struct TokenRecord {

impl TokenRecord {
pub const LEN: usize = 80;
/// Prefix values used to generate a PDA for this account.
///
/// Values are positional and appear in the following order:
///
/// 0. `TokenRecord::PREFIX.0`
/// 1. `crate::MPL_TOKEN_METADATA_ID`
/// 2. mint (`Pubkey`)
/// 3. `TokenRecord::PREFIX.1`
/// 4. token (`Pubkey`)
pub const PREFIX: (&'static [u8], &'static [u8]) =
("metadata".as_bytes(), "token_record".as_bytes());

pub fn create_pda(
mint: Pubkey,
Expand Down
Loading
Loading