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

Update mock signer interface #31

Open
wants to merge 1 commit into
base: master
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
41 changes: 40 additions & 1 deletion lib/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,27 @@ pub struct SignResult {
pub s_hex: String,
}

#[near(serializers = [json])]
pub struct AffnPnt {
pub affine_point: String,
}

#[near(serializers = [json])]
pub struct Sclr {
pub scalar: String,
}

#[near(serializers = [json])]
pub struct SignatureResponse {
pub big_r: AffnPnt,
pub s: Sclr,
pub recovery_id: u8,
}

#[allow(clippy::ptr_arg)]
#[ext_contract(ext_signer)]
pub trait SignerInterface {
fn sign(&mut self, request: SignRequest) -> PromiseOrValue<SignResult>;
fn sign(&mut self, request: SignRequest) -> PromiseOrValue<SignatureResponse>;
fn public_key(&self) -> near_sdk::PublicKey;
fn derived_public_key(
&self,
Expand Down Expand Up @@ -115,3 +132,25 @@ impl TryFrom<SignResult> for ethers_core::types::Signature {
})
}
}

impl TryFrom<SignatureResponse> for ethers_core::types::Signature {
type Error = SignResultDecodeError;

fn try_from(signature_response: SignatureResponse) -> Result<Self, Self::Error> {
let big_r = Option::<AffinePoint>::from(AffinePoint::from_bytes(
hex::decode(signature_response.big_r.affine_point)?[..].into(),
))
.ok_or(SignResultDecodeError::InvalidSignatureData)?;
let s = hex::decode(signature_response.s.scalar)?;

let r = <k256::Scalar as Reduce<<Secp256k1 as elliptic_curve::Curve>::Uint>>::reduce_bytes(
&big_r.x(),
);

Ok(ethers_core::types::Signature {
r: r.to_bytes().as_slice().into(),
s: s.as_slice().into(),
v: signature_response.recovery_id.into(),
})
}
}
21 changes: 18 additions & 3 deletions mock/signer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use lib::{
kdf::sha256,
signer::{SignRequest, SignResult, SignerInterface},
signer::{AffnPnt, Sclr, SignRequest, SignResult, SignatureResponse, SignerInterface},
Rejectable,
};
use near_sdk::{env, near, require, AccountId, PromiseOrValue, PublicKey};
Expand All @@ -23,7 +23,7 @@ pub struct MockSignerContract {}
#[near]
impl SignerInterface for MockSignerContract {
#[payable]
fn sign(&mut self, request: SignRequest) -> PromiseOrValue<SignResult> {
fn sign(&mut self, request: SignRequest) -> PromiseOrValue<SignatureResponse> {
require!(
request.key_version == KEY_VERSION,
"Key version not supported",
Expand All @@ -35,7 +35,22 @@ impl SignerInterface for MockSignerContract {
let (sig, recid) = signing_key
.sign_prehash_recoverable(&request.payload)
.unwrap();
PromiseOrValue::Value(SignResult::from_ecdsa_signature(sig, recid).unwrap())

// Create SignResult from the signature
let sign_result = SignResult::from_ecdsa_signature(sig, recid).unwrap();

// Convert SignResult to SignatureResponse
let signature_response = SignatureResponse {
big_r: AffnPnt {
affine_point: sign_result.big_r_hex,
},
s: Sclr {
scalar: sign_result.s_hex,
},
recovery_id: recid.to_byte(),
};

PromiseOrValue::Value(signature_response)
}

fn public_key(&self) -> PublicKey {
Expand Down
8 changes: 4 additions & 4 deletions nft_key/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use lib::{
chain_key::{ext_chain_key_token_approval_receiver, ChainKeyToken, ChainKeyTokenApproval},
signer::{ext_signer, SignRequest, SignResult},
signer::{ext_signer, SignRequest, SignatureResponse},
Rejectable,
};
use near_sdk::{
Expand Down Expand Up @@ -195,11 +195,11 @@ impl NftKeyContract {
#[must_use]
pub fn sign_callback(
&self,
#[callback_result] result: Result<SignResult, PromiseError>,
#[callback_result] result: Result<SignatureResponse, PromiseError>,
) -> String {
let mpc_signature = result.unwrap();
let signature_response = result.unwrap();
let ethers_signature: ethers_core::types::Signature =
mpc_signature.try_into().unwrap_or_reject();
signature_response.try_into().unwrap_or_reject();
ethers_signature.to_string()
}

Expand Down