Skip to content

Commit

Permalink
fix(ens): register name endpoint cleanup (#505)
Browse files Browse the repository at this point in the history
  • Loading branch information
geekbrother authored Feb 9, 2024
1 parent d2887c9 commit fc4c07b
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 100 deletions.
29 changes: 5 additions & 24 deletions integration/names.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ describe('Account profile names', () => {
// Generate a new eth wallet
const wallet = ethers.Wallet.createRandom();
const address = wallet.address;
const coin_type = 60; // SLIP-44 Ethereum
const chain_id = 1; // Ethereum mainnet
const coin_type = 60; // ENSIP-11 Ethereum Mainnet
const attributes = {
bio: 'integration test domain',
};
Expand All @@ -22,8 +21,6 @@ describe('Account profile names', () => {
const messageObject = {
name,
coin_type,
chain_id,
address,
attributes,
timestamp: Math.round(Date.now() / 1000)
};
Expand All @@ -40,7 +37,7 @@ describe('Account profile names', () => {
address,
};
let resp: any = await httpClient.post(
`${baseUrl}/v1/profile/account/${name}`,
`${baseUrl}/v1/profile/account`,
payload
)
expect(resp.status).toBe(401)
Expand All @@ -63,7 +60,7 @@ describe('Account profile names', () => {
address,
};
let resp: any = await httpClient.post(
`${baseUrl}/v1/profile/account/${name}`,
`${baseUrl}/v1/profile/account`,
payload
)
expect(resp.status).toBe(400)
Expand All @@ -80,7 +77,7 @@ describe('Account profile names', () => {
address,
};
let resp: any = await httpClient.post(
`${baseUrl}/v1/profile/account/${name}`,
`${baseUrl}/v1/profile/account`,
payload
)
expect(resp.status).toBe(200)
Expand All @@ -96,23 +93,7 @@ describe('Account profile names', () => {
address,
};
let resp: any = await httpClient.post(
`${baseUrl}/v1/profile/account/${name}`,
payload
)
expect(resp.status).toBe(400)
})
it('inconsistent payload', async () => {
// Name in payload is different from the one in the request path
const signature = await wallet.signMessage(message);

const payload = {
message,
signature,
coin_type,
address,
};
let resp: any = await httpClient.post(
`${baseUrl}/v1/profile/account/someothername.connect.id`,
`${baseUrl}/v1/profile/account`,
payload
)
expect(resp.status).toBe(400)
Expand Down
23 changes: 8 additions & 15 deletions src/database/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use {
crate::{
database::{error::DatabaseError, types, utils},
utils::crypto::convert_evm_chain_id_to_coin_type,
},
crate::database::{error::DatabaseError, types, utils},
chrono::{DateTime, Utc},
sqlx::{PgPool, Postgres},
std::collections::HashMap,
Expand Down Expand Up @@ -149,17 +146,13 @@ pub async fn get_addresses_by_name(
continue;
}

// Return 60 for the ETH mainnet and ENSIP-11 chain ID for other
let ensip11_chain_id = if row.chain_id == "1" {
60
} else {
convert_evm_chain_id_to_coin_type(row.chain_id.parse::<u32>().unwrap_or_default())
};

result_map.insert(ensip11_chain_id, types::Address {
address: row.address,
created_at: Some(row.created_at),
});
result_map.insert(
row.chain_id.parse::<u32>().unwrap_or_default(),
types::Address {
address: row.address,
created_at: Some(row.created_at),
},
);
}

Ok(result_map)
Expand Down
8 changes: 1 addition & 7 deletions src/handlers/profile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,6 @@ static SUPPORTED_ATTRIBUTES: Lazy<HashMap<String, Regex>> = Lazy::new(|| {
pub struct RegisterPayload {
/// Name to register
pub name: String,
/// Coin type SLIP-44
pub coin_type: u32,
/// Chain ID for the EVM
pub chain_id: u32,
/// Address
pub address: String,
/// Attributes
pub attributes: Option<HashMap<String, String>>,
/// Unixtime
Expand All @@ -50,7 +44,7 @@ pub struct RegisterRequest {
pub message: String,
/// Message signature
pub signature: String,
/// Coin type SLIP-44
/// Coin type ENSIP-11
pub coin_type: u32,
/// Address
pub address: String,
Expand Down
63 changes: 17 additions & 46 deletions src/handlers/profile/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ use {
utils::crypto::verify_message_signature,
},
axum::{
body::Bytes,
extract::{Path, State},
extract::State,
response::{IntoResponse, Response},
Json,
},
Expand All @@ -30,29 +29,18 @@ use {

pub async fn handler(
state: State<Arc<AppState>>,
name: Path<String>,
body: Bytes,
Json(register_request): Json<RegisterRequest>,
) -> Result<Response, RpcError> {
handler_internal(state, name, body)
handler_internal(state, register_request)
.with_metrics(HANDLER_TASK_METRICS.with_name("profile_register"))
.await
}

#[tracing::instrument(skip(state))]
pub async fn handler_internal(
state: State<Arc<AppState>>,
Path(name): Path<String>,
body: Bytes,
register_request: RegisterRequest,
) -> Result<Response, RpcError> {
// Check the request body format
let register_request = match serde_json::from_slice::<RegisterRequest>(&body) {
Ok(register_request_payload) => register_request_payload,
Err(e) => {
info!("Failed to deserialize register request: {}", e);
return Ok((StatusCode::BAD_REQUEST, "").into_response());
}
};

let raw_payload = &register_request.message;
let payload = match serde_json::from_str::<RegisterPayload>(raw_payload) {
Ok(payload) => payload,
Expand All @@ -62,42 +50,25 @@ pub async fn handler_internal(
}
};

if payload.name != name {
// Check for the supported ENSIP-11 coin type
if register_request.coin_type != 60 {
info!("Unsupported coin type {}", register_request.coin_type);
return Ok((
StatusCode::BAD_REQUEST,
"Name in payload and path are not equal",
"Only Ethereum Mainnet (60) coin type is supported for name registration",
)
.into_response());
}

if payload.address != register_request.address {
return Ok((
StatusCode::BAD_REQUEST,
"Address in payload request and message are not equal",
)
.into_response());
}

if payload.coin_type != register_request.coin_type {
return Ok((
StatusCode::BAD_REQUEST,
"Coin type in payload request and message are not equal",
)
.into_response());
}

// Check for the supported SLIP-44 coin types
if SupportedNamespaces::from_slip44(payload.coin_type).is_none() {
info!("Unsupported coin type {}", payload.coin_type);
return Ok((StatusCode::BAD_REQUEST, "Unsupported coin type").into_response());
}

// Check is name already registered
if get_name_and_addresses_by_name(name.clone(), &state.postgres.clone())
if get_name_and_addresses_by_name(payload.name.clone(), &state.postgres.clone())
.await
.is_ok()
{
info!("Registration request for registered name {}", name.clone());
info!(
"Registration request for already registered name {}",
payload.name.clone()
);
return Ok((StatusCode::BAD_REQUEST, "Name is already registered").into_response());
};

Expand Down Expand Up @@ -152,13 +123,13 @@ pub async fn handler_internal(
}

// Register (insert) a new domain with address
let addresses: ENSIP11AddressesMap = HashMap::from([(payload.chain_id, Address {
address: payload.address,
let addresses: ENSIP11AddressesMap = HashMap::from([(register_request.coin_type, Address {
address: register_request.address,
created_at: None,
})]);

let insert_result = insert_name(
name.clone(),
payload.name.clone(),
payload.attributes.unwrap_or(HashMap::new()),
SupportedNamespaces::Eip155,
addresses,
Expand All @@ -171,7 +142,7 @@ pub async fn handler_internal(
}

// Return the registered name and addresses
match get_name_and_addresses_by_name(name, &state.postgres.clone()).await {
match get_name_and_addresses_by_name(payload.name, &state.postgres.clone()).await {
Ok(response) => Ok(Json(response).into_response()),
Err(e) => match e {
SqlxError::RowNotFound => {
Expand Down
12 changes: 6 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,17 +215,17 @@ pub async fn bootstrap(config: Config) -> RpcResult<()> {
"/v1/account/:address/portfolio",
get(handlers::portfolio::handler),
)
// Forward lookup
// Register account name
.route(
"/v1/profile/account/:name",
get(handlers::profile::lookup::handler),
"/v1/profile/account",
post(handlers::profile::register::handler),
)
// Register
// Forward address lookup
.route(
"/v1/profile/account/:name",
post(handlers::profile::register::handler),
get(handlers::profile::lookup::handler),
)
// Reverse lookup
// Reverse name lookup
.route(
"/v1/profile/reverse/:address",
get(handlers::profile::reverse::handler),
Expand Down
3 changes: 1 addition & 2 deletions tests/functional/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,8 @@ async fn insert_and_get_name_and_addresses() {
let name = format!("{}.connect.id", generate_random_string(10));
let address = format!("0x{}", generate_random_string(16));
let namespace = types::SupportedNamespaces::Eip155;
let chain_id = 1;
let expected_ensip11_coin_type = 60;
let addresses = HashMap::from([(chain_id, types::Address {
let addresses = HashMap::from([(expected_ensip11_coin_type, types::Address {
address: address.clone(),
created_at: None,
})]);
Expand Down

0 comments on commit fc4c07b

Please sign in to comment.