mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-07-03 05:29:50 +00:00
fix(token): support external mint authority; intentional metadata supply; demo path resolver
Addresses review on PR #125 (LP-0013): #1 authority transfer now hands control to the new signer. mint and set_authority take a trailing authority_accounts (Vec<AccountWithMetadata>): empty preserves the original self/PDA-authority behavior (AMM unchanged), one entry lets an external/rotated authority actually mint or rotate again. Tests: rotated_authority_can_mint, rotated_authority_old_key_cannot_mint. #2 metadata-backed fungibles take a real mint_authority instead of a hardcoded Authority::renounced(), matching the plain-fungible supply model. Test: test_metadata_fungible_with_authority_is_mintable. #3 demo-full-flow.sh resolves TOKEN_BIN from the README-documented cargo risczero build output, falling back to the workspace build, with an explicit TOKEN_BIN override still respected. Regenerated token-idl.json for the new trailing authority_accounts.
This commit is contained in:
parent
dd8328cf9f
commit
160ff8ee4a
@ -150,6 +150,13 @@
|
||||
"writable": true,
|
||||
"signer": false,
|
||||
"init": false
|
||||
},
|
||||
{
|
||||
"name": "authority_accounts",
|
||||
"writable": false,
|
||||
"signer": false,
|
||||
"init": false,
|
||||
"rest": true
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
@ -167,6 +174,13 @@
|
||||
"writable": false,
|
||||
"signer": false,
|
||||
"init": false
|
||||
},
|
||||
{
|
||||
"name": "authority_accounts",
|
||||
"writable": false,
|
||||
"signer": false,
|
||||
"init": false,
|
||||
"rest": true
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
|
||||
@ -90,6 +90,9 @@ pub enum NewTokenDefinition {
|
||||
Fungible {
|
||||
name: String,
|
||||
total_supply: u128,
|
||||
/// Mint authority. `Some(id)` makes the token mintable by `id`; `None`
|
||||
/// fixes the supply.
|
||||
mint_authority: Option<AccountId>,
|
||||
},
|
||||
NonFungible {
|
||||
name: String,
|
||||
|
||||
@ -128,6 +128,7 @@ mod token {
|
||||
#[account(mut, signer)]
|
||||
definition_account: AccountWithMetadata,
|
||||
user_holding_account: AccountWithMetadata,
|
||||
authority_accounts: Vec<AccountWithMetadata>,
|
||||
amount_to_mint: u128,
|
||||
) -> SpelResult {
|
||||
Ok(spel_framework::SpelOutput::execute(
|
||||
@ -135,6 +136,7 @@ mod token {
|
||||
definition_account,
|
||||
user_holding_account,
|
||||
amount_to_mint,
|
||||
authority_accounts,
|
||||
ctx.self_program_id,
|
||||
),
|
||||
vec![],
|
||||
@ -147,10 +149,15 @@ mod token {
|
||||
#[instruction]
|
||||
pub fn set_authority(
|
||||
definition_account: AccountWithMetadata,
|
||||
authority_accounts: Vec<AccountWithMetadata>,
|
||||
new_authority: Option<AccountId>,
|
||||
) -> SpelResult {
|
||||
Ok(spel_framework::SpelOutput::execute(
|
||||
token_program::set_authority::set_authority(definition_account, new_authority),
|
||||
token_program::set_authority::set_authority(
|
||||
definition_account,
|
||||
new_authority,
|
||||
authority_accounts,
|
||||
),
|
||||
vec![],
|
||||
))
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ pub fn mint(
|
||||
definition_account: AccountWithMetadata,
|
||||
user_holding_account: AccountWithMetadata,
|
||||
amount_to_mint: u128,
|
||||
authority_accounts: Vec<AccountWithMetadata>,
|
||||
token_program_id: ProgramId,
|
||||
) -> Vec<AccountPostState> {
|
||||
assert_eq!(
|
||||
@ -19,17 +20,22 @@ pub fn mint(
|
||||
let mut definition = TokenDefinition::try_from(&definition_account.account.data)
|
||||
.expect("Token Definition account must be valid");
|
||||
|
||||
// Minting is gated on the definition's mint authority: the definition account
|
||||
// must be authorized in this transaction and its id must match the stored
|
||||
// authority. This holds for an external owner that signs the definition key,
|
||||
// and for a program-controlled PDA authorized via its seeds (e.g. the AMM's
|
||||
// pool definition minting LP tokens).
|
||||
// Minting is gated on the definition's stored mint authority. The proof of
|
||||
// authority is whichever account is presented as authorized AND whose id
|
||||
// matches the stored authority:
|
||||
//
|
||||
// - When `authority_accounts` is empty, the definition account itself must be the authority
|
||||
// (self/PDA authority — e.g. the AMM's LP definition minting under its own seed). This is the
|
||||
// original mint behavior.
|
||||
// - When `authority_accounts` has one entry, that account is the external authority (e.g. a
|
||||
// rotated owner key). This lets a transferred authority actually mint, as RFP-001 requires.
|
||||
if let TokenDefinition::Fungible { .. } = &definition {
|
||||
let authority = authority_accounts.first().unwrap_or(&definition_account);
|
||||
assert!(
|
||||
definition_account.is_authorized,
|
||||
authority.is_authorized,
|
||||
"Mint authority must authorize the transaction"
|
||||
);
|
||||
let signer: [u8; 32] = definition_account
|
||||
let signer: [u8; 32] = authority
|
||||
.account_id
|
||||
.as_ref()
|
||||
.try_into()
|
||||
@ -88,8 +94,17 @@ pub fn mint(
|
||||
let mut holding_post = user_holding_account.account;
|
||||
holding_post.data = Data::from(&holding);
|
||||
|
||||
vec![
|
||||
AccountPostState::new(definition_post),
|
||||
AccountPostState::new_claimed_if_default(holding_post, Claim::Authorized),
|
||||
]
|
||||
// Post-states must match pre-state order and count. Pre-state order is
|
||||
// [definition, holding, ...authority_accounts]; authority accounts are
|
||||
// read-only and pass through unchanged.
|
||||
let mut post_states = Vec::with_capacity(authority_accounts.len().saturating_add(2));
|
||||
post_states.push(AccountPostState::new(definition_post));
|
||||
post_states.push(AccountPostState::new_claimed_if_default(
|
||||
holding_post,
|
||||
Claim::Authorized,
|
||||
));
|
||||
for authority in authority_accounts {
|
||||
post_states.push(AccountPostState::new(authority.account));
|
||||
}
|
||||
post_states
|
||||
}
|
||||
|
||||
@ -116,12 +116,16 @@ pub fn new_definition_with_metadata(
|
||||
);
|
||||
|
||||
let (token_definition, token_holding) = match new_definition {
|
||||
NewTokenDefinition::Fungible { name, total_supply } => (
|
||||
NewTokenDefinition::Fungible {
|
||||
name,
|
||||
total_supply,
|
||||
mint_authority,
|
||||
} => (
|
||||
TokenDefinition::Fungible {
|
||||
name,
|
||||
total_supply,
|
||||
metadata_id: Some(metadata_target_account.account_id),
|
||||
authority: Authority::renounced(),
|
||||
authority: authority_from(mint_authority),
|
||||
},
|
||||
TokenHolding::Fungible {
|
||||
definition_id: definition_target_account.account_id,
|
||||
|
||||
@ -8,20 +8,23 @@ use token_core::TokenDefinition;
|
||||
pub fn set_authority(
|
||||
definition_account: AccountWithMetadata,
|
||||
new_authority: Option<AccountId>,
|
||||
authority_accounts: Vec<AccountWithMetadata>,
|
||||
) -> Vec<AccountPostState> {
|
||||
let mut definition = TokenDefinition::try_from(&definition_account.account.data)
|
||||
.expect("Token Definition account must be valid");
|
||||
|
||||
match &mut definition {
|
||||
TokenDefinition::Fungible { .. } => {
|
||||
// The current mint authority must authorize this transaction: the
|
||||
// definition account must be authorized and its id must match the
|
||||
// stored authority.
|
||||
// The current mint authority must authorize this transaction. As in
|
||||
// `mint`, the proof is either the definition account itself (empty
|
||||
// `authority_accounts`, self/PDA authority) or an explicit external
|
||||
// authority account (one entry), so a rotated authority can act.
|
||||
let authority = authority_accounts.first().unwrap_or(&definition_account);
|
||||
assert!(
|
||||
definition_account.is_authorized,
|
||||
authority.is_authorized,
|
||||
"Mint authority must authorize the transaction"
|
||||
);
|
||||
let signer: [u8; 32] = definition_account
|
||||
let signer: [u8; 32] = authority
|
||||
.account_id
|
||||
.as_ref()
|
||||
.try_into()
|
||||
@ -56,5 +59,11 @@ pub fn set_authority(
|
||||
let mut definition_post = definition_account.account;
|
||||
definition_post.data = Data::from(&definition);
|
||||
|
||||
vec![AccountPostState::new(definition_post)]
|
||||
// Post-states match pre-state order/count: [definition, ...authority_accounts].
|
||||
let mut post_states = Vec::with_capacity(authority_accounts.len().saturating_add(1));
|
||||
post_states.push(AccountPostState::new(definition_post));
|
||||
for authority in authority_accounts {
|
||||
post_states.push(AccountPostState::new(authority.account));
|
||||
}
|
||||
post_states
|
||||
}
|
||||
|
||||
@ -911,6 +911,7 @@ fn test_mint_not_valid_holding_account() {
|
||||
definition_account,
|
||||
holding_account,
|
||||
BalanceForTests::mint_success(),
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
}
|
||||
@ -924,6 +925,7 @@ fn test_mint_not_valid_definition_account() {
|
||||
definition_account,
|
||||
holding_account,
|
||||
BalanceForTests::mint_success(),
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
}
|
||||
@ -939,6 +941,7 @@ fn test_mint_missing_authorization() {
|
||||
definition_account,
|
||||
holding_account,
|
||||
BalanceForTests::mint_success(),
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
}
|
||||
@ -952,6 +955,7 @@ fn test_mint_rejects_foreign_owned_definition() {
|
||||
definition_account,
|
||||
holding_account,
|
||||
BalanceForTests::mint_success(),
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
}
|
||||
@ -966,6 +970,7 @@ fn test_mint_mismatched_token_definition() {
|
||||
definition_account,
|
||||
holding_account,
|
||||
BalanceForTests::mint_success(),
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
}
|
||||
@ -978,6 +983,7 @@ fn test_mint_success() {
|
||||
definition_account,
|
||||
holding_account,
|
||||
BalanceForTests::mint_success(),
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
|
||||
@ -1003,6 +1009,7 @@ fn test_mint_uninit_holding_success() {
|
||||
definition_account,
|
||||
holding_account,
|
||||
BalanceForTests::mint_success(),
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
|
||||
@ -1029,6 +1036,7 @@ fn test_mint_total_supply_overflow() {
|
||||
definition_account,
|
||||
holding_account,
|
||||
BalanceForTests::mint_overflow(),
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
}
|
||||
@ -1042,6 +1050,7 @@ fn test_mint_holding_account_overflow() {
|
||||
definition_account,
|
||||
holding_account,
|
||||
BalanceForTests::mint_overflow(),
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
}
|
||||
@ -1055,6 +1064,7 @@ fn test_mint_cannot_mint_unmintable_tokens() {
|
||||
definition_account,
|
||||
holding_account,
|
||||
BalanceForTests::mint_success(),
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
}
|
||||
@ -1067,6 +1077,7 @@ fn test_new_definition_with_metadata_success() {
|
||||
let new_definition = NewTokenDefinition::Fungible {
|
||||
name: String::from("test"),
|
||||
total_supply: 15u128,
|
||||
mint_authority: None,
|
||||
};
|
||||
let metadata = NewTokenMetadata {
|
||||
standard: MetadataStandard::Simple,
|
||||
@ -1088,6 +1099,42 @@ fn test_new_definition_with_metadata_success() {
|
||||
assert_eq!(metadata_post.required_claim(), Some(Claim::Authorized));
|
||||
}
|
||||
|
||||
/// Comment #2: a metadata-backed fungible created with `mint_authority: Some(..)`
|
||||
/// carries a real, non-renounced authority and is therefore mintable — no longer
|
||||
/// force-fixed-supply the way the hardcoded `Authority::renounced()` made it.
|
||||
#[test]
|
||||
fn test_metadata_fungible_with_authority_is_mintable() {
|
||||
let definition_account = AccountForTests::definition_account_uninit_auth();
|
||||
let holding_account = AccountForTests::holding_account_uninit_auth();
|
||||
let metadata_account = AccountForTests::metadata_account_uninit_auth();
|
||||
let new_definition = NewTokenDefinition::Fungible {
|
||||
name: String::from("test"),
|
||||
total_supply: 15u128,
|
||||
mint_authority: Some(AccountId::new([15_u8; 32])),
|
||||
};
|
||||
let metadata = NewTokenMetadata {
|
||||
standard: MetadataStandard::Simple,
|
||||
uri: "test_uri".to_string(),
|
||||
creators: "test_creators".to_string(),
|
||||
};
|
||||
let post_states = new_definition_with_metadata(
|
||||
definition_account,
|
||||
holding_account,
|
||||
metadata_account,
|
||||
new_definition,
|
||||
metadata,
|
||||
);
|
||||
let [definition_post, _holding_post, _metadata_post] = post_states.try_into().unwrap();
|
||||
|
||||
// The stored authority must be the requested key, NOT renounced.
|
||||
let def = TokenDefinition::try_from(&definition_post.account().data).unwrap();
|
||||
let stored = match def {
|
||||
TokenDefinition::Fungible { authority, .. } => authority.authority(),
|
||||
_ => None,
|
||||
};
|
||||
assert_eq!(stored, Some([15_u8; 32]));
|
||||
}
|
||||
|
||||
#[should_panic(expected = "Definition target account must be authorized")]
|
||||
#[test]
|
||||
fn test_call_new_definition_metadata_requires_authorized_definition() {
|
||||
@ -1097,6 +1144,7 @@ fn test_call_new_definition_metadata_requires_authorized_definition() {
|
||||
let new_definition = NewTokenDefinition::Fungible {
|
||||
name: String::from("test"),
|
||||
total_supply: 15u128,
|
||||
mint_authority: None,
|
||||
};
|
||||
let metadata = NewTokenMetadata {
|
||||
standard: MetadataStandard::Simple,
|
||||
@ -1121,6 +1169,7 @@ fn test_call_new_definition_metadata_requires_authorized_holding() {
|
||||
let new_definition = NewTokenDefinition::Fungible {
|
||||
name: String::from("test"),
|
||||
total_supply: 15u128,
|
||||
mint_authority: None,
|
||||
};
|
||||
let metadata = NewTokenMetadata {
|
||||
standard: MetadataStandard::Simple,
|
||||
@ -1149,6 +1198,7 @@ fn test_call_new_definition_metadata_requires_authorized_metadata() {
|
||||
let new_definition = NewTokenDefinition::Fungible {
|
||||
name: String::from("test"),
|
||||
total_supply: 15u128,
|
||||
mint_authority: None,
|
||||
};
|
||||
let metadata = NewTokenMetadata {
|
||||
standard: MetadataStandard::Simple,
|
||||
@ -1181,6 +1231,7 @@ fn test_call_new_definition_metadata_with_init_definition() {
|
||||
let new_definition = NewTokenDefinition::Fungible {
|
||||
name: String::from("test"),
|
||||
total_supply: 15u128,
|
||||
mint_authority: None,
|
||||
};
|
||||
let metadata = NewTokenMetadata {
|
||||
standard: MetadataStandard::Simple,
|
||||
@ -1213,6 +1264,7 @@ fn test_call_new_definition_metadata_with_init_metadata() {
|
||||
let new_definition = NewTokenDefinition::Fungible {
|
||||
name: String::from("test"),
|
||||
total_supply: 15u128,
|
||||
mint_authority: None,
|
||||
};
|
||||
let metadata = NewTokenMetadata {
|
||||
standard: MetadataStandard::Simple,
|
||||
@ -1245,6 +1297,7 @@ fn test_call_new_definition_metadata_with_init_holding() {
|
||||
let new_definition = NewTokenDefinition::Fungible {
|
||||
name: String::from("test"),
|
||||
total_supply: 15u128,
|
||||
mint_authority: None,
|
||||
};
|
||||
let metadata = NewTokenMetadata {
|
||||
standard: MetadataStandard::Simple,
|
||||
@ -1418,6 +1471,7 @@ mod authority_tests {
|
||||
def_with_authority(),
|
||||
holding_account(),
|
||||
50_000,
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
let [def_post, holding_post] = post_states.try_into().unwrap();
|
||||
@ -1448,6 +1502,7 @@ mod authority_tests {
|
||||
def_with_authority_revoked(),
|
||||
holding_account(),
|
||||
50_000,
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
}
|
||||
@ -1457,7 +1512,7 @@ mod authority_tests {
|
||||
fn mint_without_is_authorized_fails() {
|
||||
let mut def = def_with_authority();
|
||||
def.is_authorized = false;
|
||||
let _ = mint(def, holding_account(), 50_000, TOKEN_PROGRAM_ID);
|
||||
let _ = mint(def, holding_account(), 50_000, vec![], TOKEN_PROGRAM_ID);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1467,6 +1522,7 @@ mod authority_tests {
|
||||
def_wrong_authority(),
|
||||
holding_account(),
|
||||
50_000,
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
}
|
||||
@ -1474,13 +1530,17 @@ mod authority_tests {
|
||||
#[test]
|
||||
#[should_panic(expected = "New mint authority must be a valid non-zero account ID")]
|
||||
fn set_authority_rejects_zero_new_authority() {
|
||||
let _ = set_authority(def_with_authority(), Some(AccountId::new([0u8; 32])));
|
||||
let _ = set_authority(
|
||||
def_with_authority(),
|
||||
Some(AccountId::new([0u8; 32])),
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_authority_rotates_to_new_key() {
|
||||
let new_key = AccountId::new([7_u8; 32]);
|
||||
let post_states = set_authority(def_with_authority(), Some(new_key));
|
||||
let post_states = set_authority(def_with_authority(), Some(new_key), vec![]);
|
||||
let [def_post] = post_states.try_into().unwrap();
|
||||
|
||||
let def = TokenDefinition::try_from(&def_post.account().data).unwrap();
|
||||
@ -1493,7 +1553,7 @@ mod authority_tests {
|
||||
|
||||
#[test]
|
||||
fn set_authority_revokes_permanently() {
|
||||
let post_states = set_authority(def_with_authority(), None);
|
||||
let post_states = set_authority(def_with_authority(), None, vec![]);
|
||||
let [def_post] = post_states.try_into().unwrap();
|
||||
|
||||
let def = TokenDefinition::try_from(&def_post.account().data).unwrap();
|
||||
@ -1510,6 +1570,7 @@ mod authority_tests {
|
||||
let _ = set_authority(
|
||||
def_with_authority_revoked(),
|
||||
Some(AccountId::new([7_u8; 32])),
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
@ -1518,19 +1579,23 @@ mod authority_tests {
|
||||
fn set_authority_without_is_authorized_fails() {
|
||||
let mut def = def_with_authority();
|
||||
def.is_authorized = false;
|
||||
let _ = set_authority(def, Some(AccountId::new([7_u8; 32])));
|
||||
let _ = set_authority(def, Some(AccountId::new([7_u8; 32])), vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "SetAuthority failed")]
|
||||
fn set_authority_wrong_signer_fails() {
|
||||
let _ = set_authority(def_wrong_authority(), Some(AccountId::new([7_u8; 32])));
|
||||
let _ = set_authority(
|
||||
def_wrong_authority(),
|
||||
Some(AccountId::new([7_u8; 32])),
|
||||
vec![],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_authority_rotate_then_old_cannot_mint() {
|
||||
let new_key = AccountId::new([7_u8; 32]);
|
||||
let post_states = set_authority(def_with_authority(), Some(new_key));
|
||||
let post_states = set_authority(def_with_authority(), Some(new_key), vec![]);
|
||||
let [def_post] = post_states.try_into().unwrap();
|
||||
|
||||
let def = TokenDefinition::try_from(&def_post.account().data).unwrap();
|
||||
@ -1542,4 +1607,82 @@ mod authority_tests {
|
||||
assert_eq!(auth, Some([7_u8; 32]));
|
||||
assert_ne!(auth, Some(AUTHORITY));
|
||||
}
|
||||
|
||||
/// Authority signer for the rotated key B ([7;32]), authorized.
|
||||
fn new_authority_signer() -> AccountWithMetadata {
|
||||
AccountWithMetadata {
|
||||
account: Account::default(),
|
||||
is_authorized: true,
|
||||
account_id: AccountId::new([7_u8; 32]),
|
||||
}
|
||||
}
|
||||
|
||||
/// RFP-001 end-to-end (comment #1): after rotating authority A -> B, the new
|
||||
/// authority B can actually mint by presenting itself in `authority_accounts`.
|
||||
#[test]
|
||||
fn rotated_authority_can_mint() {
|
||||
// Rotate A ([15;32]) -> B ([7;32]), signed by A via self-authority.
|
||||
let rotate_post = set_authority(
|
||||
def_with_authority(),
|
||||
Some(AccountId::new([7_u8; 32])),
|
||||
vec![],
|
||||
);
|
||||
let [def_post] = rotate_post.try_into().unwrap();
|
||||
|
||||
// Rebuild the definition carrying the rotated authority, re-authorized.
|
||||
let mut rotated_def = def_with_authority();
|
||||
rotated_def.account = def_post.account().clone();
|
||||
|
||||
// B mints by presenting itself as the external authority.
|
||||
let mint_post = mint(
|
||||
rotated_def,
|
||||
holding_account(),
|
||||
10_000,
|
||||
vec![new_authority_signer()],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
let [def_after, holding_after, _auth] = mint_post.try_into().unwrap();
|
||||
let minted = TokenDefinition::try_from(&def_after.account().data).unwrap();
|
||||
assert!(matches!(
|
||||
minted,
|
||||
TokenDefinition::Fungible {
|
||||
total_supply: 110_000,
|
||||
..
|
||||
}
|
||||
));
|
||||
let holding = TokenHolding::try_from(&holding_after.account().data).unwrap();
|
||||
assert!(matches!(
|
||||
holding,
|
||||
TokenHolding::Fungible {
|
||||
balance: 11_000,
|
||||
..
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
/// Comment #1 negative: after rotation to B, the OLD authority A can no
|
||||
/// longer mint. Here A attempts self-authority (empty `authority_accounts`),
|
||||
/// but the definition's own id no longer matches the stored authority B.
|
||||
#[test]
|
||||
#[should_panic(expected = "Mint authority check failed")]
|
||||
fn rotated_authority_old_key_cannot_mint() {
|
||||
let rotate_post = set_authority(
|
||||
def_with_authority(),
|
||||
Some(AccountId::new([7_u8; 32])),
|
||||
vec![],
|
||||
);
|
||||
let [def_post] = rotate_post.try_into().unwrap();
|
||||
|
||||
let mut rotated_def = def_with_authority();
|
||||
rotated_def.account = def_post.account().clone();
|
||||
|
||||
// A ([15;32]) is no longer the authority; self-authority must fail.
|
||||
let _ = mint(
|
||||
rotated_def,
|
||||
holding_account(),
|
||||
10_000,
|
||||
vec![],
|
||||
TOKEN_PROGRAM_ID,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,22 @@ fi
|
||||
SPEL="${SPEL:-$HOME/rebase-lez/spel/target/release/spel}"
|
||||
LEZ_PROGRAMS="${LEZ_PROGRAMS:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
||||
IDL="${IDL:-$LEZ_PROGRAMS/artifacts/token-idl.json}"
|
||||
TOKEN_BIN="${TOKEN_BIN:-$LEZ_PROGRAMS/target/riscv-guest/token-methods/token-guest/riscv32im-risc0-zkvm-elf/release/token.bin}"
|
||||
# Resolve the token guest binary from either build layout, in priority order:
|
||||
# 1. `cargo risczero build --manifest-path programs/token/methods/guest/Cargo.toml`
|
||||
# -> programs/token/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/token.bin
|
||||
# (the build command documented in the README)
|
||||
# 2. workspace build (`cargo build` / `cargo test`)
|
||||
# -> target/riscv-guest/token-methods/token-guest/riscv32im-risc0-zkvm-elf/release/token.bin
|
||||
# An explicit TOKEN_BIN env var always takes precedence.
|
||||
_risc0_token_bin="$LEZ_PROGRAMS/programs/token/methods/guest/target/riscv32im-risc0-zkvm-elf/docker/token.bin"
|
||||
_workspace_token_bin="$LEZ_PROGRAMS/target/riscv-guest/token-methods/token-guest/riscv32im-risc0-zkvm-elf/release/token.bin"
|
||||
if [ -z "${TOKEN_BIN:-}" ]; then
|
||||
if [ -f "$_risc0_token_bin" ]; then
|
||||
TOKEN_BIN="$_risc0_token_bin"
|
||||
else
|
||||
TOKEN_BIN="$_workspace_token_bin"
|
||||
fi
|
||||
fi
|
||||
DEMO_DIR="${DEMO_DIR:-$(pwd)}"
|
||||
WALLET_DIR="${WALLET_DIR:-$DEMO_DIR/.scaffold/wallet}"
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user