Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit fb94974

Browse files
dr497mvines
authored andcommitted
name service: allow parent name owner to update records
1 parent 02d2736 commit fb94974

File tree

6 files changed

+41
-6
lines changed

6 files changed

+41
-6
lines changed

name-service/js/src/bindings.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ export async function updateNameRegistryData(
123123
nameAccountKey,
124124
new Numberu32(offset),
125125
input_data,
126-
signer
126+
signer,
127+
nameParent
127128
);
128129

129130
return updateInstr;

name-service/js/src/instructions.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ export function updateInstruction(
9494
nameAccountKey: PublicKey,
9595
offset: Numberu32,
9696
input_data: Buffer,
97-
nameUpdateSigner: PublicKey
97+
nameUpdateSigner: PublicKey,
98+
parentNameKey: PublicKey | undefined
9899
): TransactionInstruction {
99100
const buffers = [
100101
Buffer.from(Int8Array.from([1])),
@@ -104,7 +105,7 @@ export function updateInstruction(
104105
];
105106

106107
const data = Buffer.concat(buffers);
107-
const keys = [
108+
let keys = [
108109
{
109110
pubkey: nameAccountKey,
110111
isSigner: false,
@@ -117,6 +118,14 @@ export function updateInstruction(
117118
},
118119
];
119120

121+
if (parentNameKey) {
122+
keys.push({
123+
pubkey: parentNameKey,
124+
isSigner: false,
125+
isWritable: false,
126+
});
127+
}
128+
120129
return new TransactionInstruction({
121130
keys,
122131
programId: nameProgramId,

name-service/js/src/twitter.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ export async function changeTwitterRegistryData(
103103
twitterHandleRegistryKey,
104104
new Numberu32(offset),
105105
input_data,
106-
verifiedPubkey
106+
verifiedPubkey,
107+
undefined
107108
),
108109
];
109110

@@ -441,7 +442,8 @@ export async function createReverseTwitterRegistry(
441442
reverseRegistryKey,
442443
new Numberu32(0),
443444
Buffer.from(reverseTwitterRegistryStateBuff),
444-
TWITTER_VERIFICATION_AUTHORITY
445+
TWITTER_VERIFICATION_AUTHORITY,
446+
undefined
445447
),
446448
];
447449
}

name-service/program/src/instruction.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ pub enum NameRegistryInstruction {
5353
/// 0. `[writeable]` Name record to be updated
5454
/// 1. `[signer]` Account class
5555
///
56+
/// * If the signer is the parent name account owner
57+
/// 0. `[writeable]` Name record to be updated
58+
/// 1. `[signer]` Parent name account owner
59+
/// 2. `[]` Parent name record
5660
Update { offset: u32, data: Vec<u8> },
5761

5862
/// Transfer ownership of a name record
@@ -127,14 +131,19 @@ pub fn update(
127131
data: Vec<u8>,
128132
name_account_key: Pubkey,
129133
name_update_signer: Pubkey,
134+
name_parent: Option<Pubkey>,
130135
) -> Result<Instruction, ProgramError> {
131136
let instruction_data = NameRegistryInstruction::Update { offset, data };
132137
let data = instruction_data.try_to_vec().unwrap();
133-
let accounts = vec![
138+
let mut accounts = vec![
134139
AccountMeta::new(name_account_key, false),
135140
AccountMeta::new_readonly(name_update_signer, true),
136141
];
137142

143+
if let Some(name_parent_key) = name_parent {
144+
accounts.push(AccountMeta::new(name_parent_key, false))
145+
}
146+
138147
Ok(Instruction {
139148
program_id: name_service_program_id,
140149
accounts,

name-service/program/src/processor.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,22 @@ impl Processor {
124124

125125
let name_account = next_account_info(accounts_iter)?;
126126
let name_update_signer = next_account_info(accounts_iter)?;
127+
let parent_name = next_account_info(accounts_iter).ok();
127128

128129
let name_record_header = NameRecordHeader::unpack_from_slice(&name_account.data.borrow())?;
129130

130131
// Verifications
132+
let is_parent_owner = if let Some(parent_name) = parent_name {
133+
if name_record_header.parent_name != *parent_name.key {
134+
msg!("Invalid parent name account");
135+
return Err(ProgramError::InvalidArgument);
136+
}
137+
let parent_name_record_header =
138+
NameRecordHeader::unpack_from_slice(&parent_name.data.borrow())?;
139+
parent_name_record_header.owner == *name_update_signer.key
140+
} else {
141+
false
142+
};
131143
if !name_update_signer.is_signer {
132144
msg!("The given name class or owner is not a signer.");
133145
return Err(ProgramError::InvalidArgument);
@@ -140,6 +152,7 @@ impl Processor {
140152
}
141153
if name_record_header.class == Pubkey::default()
142154
&& *name_update_signer.key != name_record_header.owner
155+
&& !is_parent_owner
143156
{
144157
msg!("The given name owner account is incorrect.");
145158
return Err(ProgramError::InvalidArgument);

name-service/program/tests/functional.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ async fn test_name_service() {
130130
data,
131131
name_account_key,
132132
sol_subdomains_class.pubkey(),
133+
Some(name_record_header.parent_name),
133134
)
134135
.unwrap();
135136
sign_send_instruction(&mut ctx, update_instruction, vec![&sol_subdomains_class])

0 commit comments

Comments
 (0)