mirror of
https://github.com/logos-messaging/OpChan.git
synced 2026-01-04 05:43:10 +00:00
debugging
This commit is contained in:
parent
1dfd790b11
commit
d9d24dfc4f
@ -125,11 +125,27 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
};
|
||||
|
||||
const getVerificationStatus = (user: User): VerificationStatus => {
|
||||
console.log(`🔍 Checking verification status for user:`, {
|
||||
address: user.address,
|
||||
walletType: user.walletType,
|
||||
ordinalOwnership: user.ordinalOwnership,
|
||||
ensOwnership: user.ensOwnership,
|
||||
ensName: user.ensName,
|
||||
hasDelegation: !!user.delegationSignature,
|
||||
delegationExpiry: user.delegationExpiry ? new Date(user.delegationExpiry).toISOString() : 'none'
|
||||
});
|
||||
|
||||
if (user.walletType === 'bitcoin') {
|
||||
return user.ordinalOwnership ? 'verified-owner' : 'verified-none';
|
||||
const status = user.ordinalOwnership ? 'verified-owner' : 'verified-none';
|
||||
console.log(`📊 Bitcoin verification result:`, { status, hasOrdinal: !!user.ordinalOwnership });
|
||||
return status;
|
||||
} else if (user.walletType === 'ethereum') {
|
||||
return user.ensOwnership ? 'verified-owner' : 'verified-none';
|
||||
const status = user.ensOwnership ? 'verified-owner' : 'verified-none';
|
||||
console.log(`📊 Ethereum verification result:`, { status, hasENS: !!user.ensOwnership, ensName: user.ensName });
|
||||
return status;
|
||||
}
|
||||
|
||||
console.log(`📊 Default verification result: unverified`);
|
||||
return 'unverified';
|
||||
};
|
||||
|
||||
@ -303,10 +319,10 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
|
||||
const messageSigning = {
|
||||
signMessage: async (message: OpchanMessage): Promise<OpchanMessage | null> => {
|
||||
return authServiceRef.current.signMessage(message);
|
||||
return authServiceRef.current.messageSigning.signMessage(message);
|
||||
},
|
||||
verifyMessage: async (message: OpchanMessage): Promise<boolean> => {
|
||||
return authServiceRef.current.verifyMessage(message);
|
||||
return authServiceRef.current.messageSigning.verifyMessage(message);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ export function ForumProvider({ children }: { children: React.ReactNode }) {
|
||||
const updateStateFromCache = useCallback(() => {
|
||||
// Use the verifyMessage function from authService if available
|
||||
const verifyFn = isAuthenticated ?
|
||||
(message: OpchanMessage) => authService.verifyMessage(message) :
|
||||
(message: OpchanMessage) => authService.messageSigning.verifyMessage(message) :
|
||||
undefined;
|
||||
|
||||
// Build user verification status for relevance calculation
|
||||
|
||||
@ -15,13 +15,13 @@ export interface AuthResult {
|
||||
|
||||
export class AuthService {
|
||||
private walletService: WalletService;
|
||||
private ordinalApi: OrdinalAPI;
|
||||
private messageSigning: MessageSigning;
|
||||
private ordinalAPI: OrdinalAPI;
|
||||
public messageSigning: MessageSigning;
|
||||
private keyDelegation: KeyDelegation;
|
||||
|
||||
constructor() {
|
||||
this.walletService = new WalletService();
|
||||
this.ordinalApi = new OrdinalAPI();
|
||||
this.ordinalAPI = new OrdinalAPI();
|
||||
this.keyDelegation = new KeyDelegation();
|
||||
this.messageSigning = new MessageSigning(this.keyDelegation);
|
||||
}
|
||||
@ -280,19 +280,7 @@ export class AuthService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign a message using delegated key
|
||||
*/
|
||||
async signMessage(message: OpchanMessage): Promise<OpchanMessage | null> {
|
||||
return this.messageSigning.signMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a message signature
|
||||
*/
|
||||
async verifyMessage(message: OpchanMessage): Promise<boolean> {
|
||||
return this.messageSigning.verifyMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if delegation is valid
|
||||
|
||||
@ -20,7 +20,7 @@ export class MessageService {
|
||||
*/
|
||||
async signAndSendMessage(message: OpchanMessage): Promise<MessageResult> {
|
||||
try {
|
||||
const signedMessage = await this.authService.signMessage(message);
|
||||
const signedMessage = this.authService.messageSigning.signMessage(message);
|
||||
|
||||
if (!signedMessage) {
|
||||
// Check if delegation exists but is expired
|
||||
@ -66,6 +66,6 @@ export class MessageService {
|
||||
* Verify a message signature
|
||||
*/
|
||||
async verifyMessage(message: OpchanMessage): Promise<boolean> {
|
||||
return this.authService.verifyMessage(message);
|
||||
return this.authService.messageSigning.verifyMessage(message);
|
||||
}
|
||||
}
|
||||
@ -145,17 +145,49 @@ export class KeyDelegation {
|
||||
|
||||
// If a current address is provided, validate it matches the delegation
|
||||
if (currentAddress && delegation.walletAddress !== currentAddress) {
|
||||
console.warn(`⚠️ Delegation address mismatch detected:`, {
|
||||
storedAddress: delegation.walletAddress,
|
||||
currentAddress: currentAddress,
|
||||
suggestion: 'Consider clearing the delegation and creating a new one'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// If a current wallet type is provided, validate it matches the delegation
|
||||
if (currentWalletType && delegation.walletType !== currentWalletType) {
|
||||
console.warn(`⚠️ Delegation wallet type mismatch detected:`, {
|
||||
storedType: delegation.walletType,
|
||||
currentType: currentWalletType,
|
||||
suggestion: 'Consider clearing the delegation and creating a new one'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current wallet address matches the stored delegation
|
||||
* @param currentAddress The current wallet address to check
|
||||
* @returns boolean indicating if addresses match
|
||||
*/
|
||||
isAddressMatch(currentAddress: string): boolean {
|
||||
const delegation = this.retrieveDelegation();
|
||||
if (!delegation) return false;
|
||||
|
||||
const matches = delegation.walletAddress === currentAddress;
|
||||
|
||||
if (!matches) {
|
||||
console.warn(`⚠️ Wallet address mismatch:`, {
|
||||
storedAddress: delegation.walletAddress,
|
||||
currentAddress: currentAddress,
|
||||
timeRemaining: this.getDelegationTimeRemaining()
|
||||
});
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs a message using the browser-generated private key
|
||||
* @param message The message to sign
|
||||
|
||||
@ -10,13 +10,26 @@ export class MessageSigning {
|
||||
}
|
||||
|
||||
signMessage<T extends OpchanMessage>(message: T): T | null {
|
||||
const messageId = 'id' in message ? message.id : `${message.type}-${message.timestamp}`;
|
||||
console.log(`✍️ Starting message signing for: ${messageId}`);
|
||||
|
||||
if (!this.keyDelegation.isDelegationValid()) {
|
||||
console.error('No valid key delegation found. Cannot sign message.');
|
||||
console.error(`❌ No valid key delegation found. Cannot sign message: ${messageId}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const delegation = this.keyDelegation.retrieveDelegation();
|
||||
if (!delegation) return null;
|
||||
if (!delegation) {
|
||||
console.error(`❌ No delegation found. Cannot sign message: ${messageId}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log(`🔑 Using delegation for signing:`, {
|
||||
walletAddress: delegation.walletAddress,
|
||||
walletType: delegation.walletType,
|
||||
browserPubKey: delegation.browserPublicKey.slice(0, 16) + '...',
|
||||
expiresAt: new Date(delegation.expiryTimestamp).toISOString()
|
||||
});
|
||||
|
||||
const messageToSign = JSON.stringify({
|
||||
...message,
|
||||
@ -27,10 +40,23 @@ export class MessageSigning {
|
||||
delegationExpiry: undefined
|
||||
});
|
||||
|
||||
const signature = this.keyDelegation.signMessage(messageToSign);
|
||||
if (!signature) return null;
|
||||
console.log(`📝 Signing message content for ${messageId}:`, {
|
||||
contentLength: messageToSign.length,
|
||||
messageType: message.type
|
||||
});
|
||||
|
||||
return {
|
||||
const signature = this.keyDelegation.signMessage(messageToSign);
|
||||
if (!signature) {
|
||||
console.error(`❌ Failed to sign message: ${messageId}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log(`✅ Message signed successfully for ${messageId}:`, {
|
||||
signatureLength: signature.length,
|
||||
signaturePrefix: signature.slice(0, 16) + '...'
|
||||
});
|
||||
|
||||
const signedMessage = {
|
||||
...message,
|
||||
signature,
|
||||
browserPubKey: delegation.browserPublicKey,
|
||||
@ -42,6 +68,10 @@ export class MessageSigning {
|
||||
),
|
||||
delegationExpiry: delegation.expiryTimestamp
|
||||
};
|
||||
|
||||
console.log(`🎉 Message signing completed for ${messageId} with delegation chain`);
|
||||
|
||||
return signedMessage;
|
||||
}
|
||||
|
||||
async verifyMessage(message: OpchanMessage & {
|
||||
@ -51,20 +81,42 @@ export class MessageSigning {
|
||||
delegationMessage?: string;
|
||||
delegationExpiry?: number;
|
||||
}): Promise<boolean> {
|
||||
const messageId = 'id' in message ? message.id : `${message.type}-${message.timestamp}`;
|
||||
console.log(`🔍 Starting verification for message: ${messageId}`);
|
||||
|
||||
// Check for required signature fields
|
||||
if (!message.signature || !message.browserPubKey) {
|
||||
const messageId = 'id' in message ? message.id : `${message.type}-${message.timestamp}`;
|
||||
console.warn('Message is missing signature information', messageId);
|
||||
console.warn(`❌ Message ${messageId} missing signature information:`, {
|
||||
hasSignature: !!message.signature,
|
||||
hasBrowserPubKey: !!message.browserPubKey
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for required delegation fields
|
||||
if (!message.delegationSignature || !message.delegationMessage || !message.delegationExpiry) {
|
||||
const messageId = 'id' in message ? message.id : `${message.type}-${message.timestamp}`;
|
||||
console.warn('Message is missing delegation information', messageId);
|
||||
console.warn(`❌ Message ${messageId} missing delegation information:`, {
|
||||
hasDelegationSignature: !!message.delegationSignature,
|
||||
hasDelegationMessage: !!message.delegationMessage,
|
||||
hasDelegationExpiry: !!message.delegationExpiry
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(`✅ Message ${messageId} has all required fields`);
|
||||
|
||||
// Log delegation details for debugging
|
||||
const delegation = this.keyDelegation.retrieveDelegation();
|
||||
if (delegation) {
|
||||
console.log(`🔍 Current delegation details:`, {
|
||||
storedWalletAddress: delegation.walletAddress,
|
||||
messageAuthorAddress: message.author,
|
||||
addressesMatch: delegation.walletAddress === message.author,
|
||||
walletType: delegation.walletType,
|
||||
hasWalletPublicKey: !!delegation.walletPublicKey
|
||||
});
|
||||
}
|
||||
|
||||
// 1. Verify the message signature
|
||||
const signedContent = JSON.stringify({
|
||||
...message,
|
||||
@ -75,6 +127,8 @@ export class MessageSigning {
|
||||
delegationExpiry: undefined
|
||||
});
|
||||
|
||||
console.log(`🔐 Verifying message signature for ${messageId} with browser key: ${message.browserPubKey.slice(0, 16)}...`);
|
||||
|
||||
const isValidMessageSignature = this.keyDelegation.verifySignature(
|
||||
signedContent,
|
||||
message.signature,
|
||||
@ -82,19 +136,31 @@ export class MessageSigning {
|
||||
);
|
||||
|
||||
if (!isValidMessageSignature) {
|
||||
const messageId = 'id' in message ? message.id : `${message.type}-${message.timestamp}`;
|
||||
console.warn(`Invalid message signature for message ${messageId}`);
|
||||
console.warn(`❌ Invalid message signature for ${messageId}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(`✅ Message signature verified for ${messageId}`);
|
||||
|
||||
// 2. Verify delegation hasn't expired
|
||||
const now = Date.now();
|
||||
const timeUntilExpiry = message.delegationExpiry - now;
|
||||
|
||||
console.log(`⏰ Checking delegation expiry for ${messageId}:`, {
|
||||
currentTime: new Date(now).toISOString(),
|
||||
expiryTime: new Date(message.delegationExpiry).toISOString(),
|
||||
timeUntilExpiry: `${Math.round(timeUntilExpiry / 1000 / 60)} minutes`
|
||||
});
|
||||
|
||||
if (now >= message.delegationExpiry) {
|
||||
const messageId = 'id' in message ? message.id : `${message.type}-${message.timestamp}`;
|
||||
console.warn(`Delegation expired for message ${messageId}`);
|
||||
console.warn(`❌ Delegation expired for ${messageId}`, {
|
||||
expiredBy: `${Math.round(-timeUntilExpiry / 1000 / 60)} minutes`
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(`✅ Delegation not expired for ${messageId}`);
|
||||
|
||||
// 3. Verify delegation message integrity
|
||||
const expectedDelegationMessage = this.keyDelegation.createDelegationMessage(
|
||||
message.browserPubKey,
|
||||
@ -102,25 +168,71 @@ export class MessageSigning {
|
||||
message.delegationExpiry
|
||||
);
|
||||
|
||||
console.log(`🔗 Verifying delegation message integrity for ${messageId}:`, {
|
||||
expected: expectedDelegationMessage,
|
||||
actual: message.delegationMessage,
|
||||
matches: message.delegationMessage === expectedDelegationMessage
|
||||
});
|
||||
|
||||
if (message.delegationMessage !== expectedDelegationMessage) {
|
||||
const messageId = 'id' in message ? message.id : `${message.type}-${message.timestamp}`;
|
||||
console.warn(`Delegation message tampered for message ${messageId}`);
|
||||
console.warn(`❌ Delegation message tampered for ${messageId}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(`✅ Delegation message integrity verified for ${messageId}`);
|
||||
|
||||
// 4. Verify wallet signature of delegation
|
||||
console.log(`🔑 Verifying wallet signature for ${messageId} from author: ${message.author}`);
|
||||
|
||||
const isValidDelegationSignature = await this.verifyWalletSignature(
|
||||
message.delegationMessage,
|
||||
message.delegationSignature,
|
||||
message.author
|
||||
);
|
||||
|
||||
console.log(`🔍 Delegation verification details:`, {
|
||||
delegationMessage: message.delegationMessage,
|
||||
delegationSignature: message.delegationSignature,
|
||||
signatureLength: message.delegationSignature?.length,
|
||||
messageAuthor: message.author,
|
||||
storedDelegation: delegation ? {
|
||||
signature: delegation.signature,
|
||||
signatureLength: delegation.signature?.length,
|
||||
walletAddress: delegation.walletAddress
|
||||
} : 'no delegation found'
|
||||
});
|
||||
|
||||
if (!isValidDelegationSignature) {
|
||||
const messageId = 'id' in message ? message.id : `${message.type}-${message.timestamp}`;
|
||||
console.warn(`Invalid delegation signature for message ${messageId}`);
|
||||
console.warn(`❌ Invalid delegation signature for ${messageId}`);
|
||||
console.log(`🔍 Delegation signature verification failed. This could indicate:`, {
|
||||
reason: 'Address mismatch between delegation creation and current wallet',
|
||||
suggestion: 'User may have switched wallets or accounts. Try creating a new delegation.',
|
||||
delegationMessage: message.delegationMessage,
|
||||
delegationSignature: message.delegationSignature.slice(0, 32) + '...',
|
||||
expectedAuthor: message.author
|
||||
});
|
||||
|
||||
// Show a user-friendly error message
|
||||
console.error(`🚨 SECURITY ALERT: Delegation signature verification failed for message ${messageId}.
|
||||
|
||||
This usually means:
|
||||
1. You switched wallet accounts since creating the delegation
|
||||
2. You're using a different wallet than the one that created the delegation
|
||||
3. Your wallet address changed (e.g., switching networks)
|
||||
|
||||
To fix this:
|
||||
1. Go to your profile/settings
|
||||
2. Click "Clear Delegation"
|
||||
3. Create a new delegation with your current wallet
|
||||
|
||||
This ensures your messages are properly authenticated with your current wallet address.`);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(`✅ Wallet signature verified for ${messageId}`);
|
||||
console.log(`🎉 All verifications passed for message: ${messageId}`);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
138
src/lib/identity/signatures/wallet-signature-verifier.ts
Normal file
138
src/lib/identity/signatures/wallet-signature-verifier.ts
Normal file
@ -0,0 +1,138 @@
|
||||
/**
|
||||
* Wallet signature verification for delegation messages
|
||||
*
|
||||
* This module handles cryptographic verification of wallet signatures
|
||||
* for Bitcoin and Ethereum wallets when they sign delegation messages.
|
||||
*/
|
||||
|
||||
import * as secp256k1 from '@noble/secp256k1';
|
||||
import { sha256 } from '@noble/hashes/sha256';
|
||||
import { bytesToHex, hexToBytes } from '@/lib/utils';
|
||||
import { recoverMessageAddress, getAddress, verifyMessage as viemVerifyMessage } from 'viem';
|
||||
|
||||
export class WalletSignatureVerifier {
|
||||
|
||||
/**
|
||||
* Verify a Bitcoin wallet signature
|
||||
* @param message The original message that was signed
|
||||
* @param signature The signature in hex format
|
||||
* @param publicKey The public key in hex format
|
||||
* @returns boolean indicating if the signature is valid
|
||||
*/
|
||||
static verifyBitcoinSignature(
|
||||
message: string,
|
||||
signature: string,
|
||||
publicKey: string
|
||||
): boolean {
|
||||
console.log(`🔐 Verifying Bitcoin signature:`, {
|
||||
messageLength: message.length,
|
||||
signatureLength: signature.length,
|
||||
publicKeyLength: publicKey.length,
|
||||
publicKeyPrefix: publicKey.slice(0, 16) + '...'
|
||||
});
|
||||
|
||||
try {
|
||||
const messageBytes = new TextEncoder().encode(message);
|
||||
const messageHash = sha256(messageBytes);
|
||||
const signatureBytes = hexToBytes(signature);
|
||||
const publicKeyBytes = hexToBytes(publicKey);
|
||||
|
||||
const isValid = secp256k1.verify(signatureBytes, messageHash, publicKeyBytes);
|
||||
|
||||
console.log(`✅ Bitcoin signature verification result:`, {
|
||||
isValid,
|
||||
messageHash: bytesToHex(messageHash).slice(0, 16) + '...'
|
||||
});
|
||||
|
||||
return isValid;
|
||||
} catch (error) {
|
||||
console.error('❌ Error verifying Bitcoin signature:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify an Ethereum wallet signature using viem (EIP-191 personal_sign)
|
||||
* @param message The original message that was signed
|
||||
* @param signature The signature in hex format (0x...)
|
||||
* @param address The Ethereum address expected to have signed the message
|
||||
*/
|
||||
static async verifyEthereumSignature(
|
||||
message: string,
|
||||
signature: string,
|
||||
address: string
|
||||
): Promise<boolean> {
|
||||
console.log(`🔐 Verifying Ethereum signature:`, {
|
||||
messageLength: message.length,
|
||||
signatureLength: signature.length,
|
||||
expectedAddress: address,
|
||||
signaturePrefix: signature.slice(0, 16) + '...',
|
||||
fullMessage: message // Log the full message for debugging
|
||||
});
|
||||
|
||||
try {
|
||||
// First, use viem's built-in verifier (handles prefixing correctly)
|
||||
const isValid = await viemVerifyMessage({ message, signature: signature as `0x${string}`, address: getAddress(address) as `0x${string}` });
|
||||
|
||||
// For diagnostics only, attempt recovery
|
||||
try {
|
||||
const recovered = await recoverMessageAddress({ message, signature: signature as `0x${string}` });
|
||||
console.log(`🔍 Ethereum signature recovery details:`, {
|
||||
recoveredAddress: recovered,
|
||||
expectedAddress: address,
|
||||
recoveredNormalized: getAddress(recovered),
|
||||
expectedNormalized: getAddress(address),
|
||||
addressesMatch: getAddress(recovered) === getAddress(address),
|
||||
rawComparison: recovered === address,
|
||||
messageBytes: new TextEncoder().encode(message).length,
|
||||
signatureBytes: signature.length
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn('⚠️ Non-fatal: recoverMessageAddress failed during diagnostics:', e);
|
||||
}
|
||||
|
||||
console.log(`✅ Ethereum signature verification result:`, { isValid });
|
||||
return isValid;
|
||||
} catch (error) {
|
||||
console.error('❌ Error verifying Ethereum signature:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify wallet signature based on wallet type
|
||||
* @param message The original message that was signed
|
||||
* @param signature The signature in hex format
|
||||
* @param walletAddress The wallet address
|
||||
* @param walletType The type of wallet (bitcoin or ethereum)
|
||||
* @param publicKey Optional public key for Bitcoin verification
|
||||
*/
|
||||
static async verifyWalletSignature(
|
||||
message: string,
|
||||
signature: string,
|
||||
walletAddress: string,
|
||||
walletType: 'bitcoin' | 'ethereum',
|
||||
publicKey?: string
|
||||
): Promise<boolean> {
|
||||
console.log(`🔑 Starting wallet signature verification:`, {
|
||||
walletType,
|
||||
walletAddress,
|
||||
hasPublicKey: !!publicKey,
|
||||
messageLength: message.length
|
||||
});
|
||||
|
||||
if (walletType === 'bitcoin') {
|
||||
if (!publicKey) {
|
||||
console.warn(`❌ Bitcoin verification requires public key but none provided`);
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(`🔐 Using Bitcoin verification path`);
|
||||
return this.verifyBitcoinSignature(message, signature, publicKey);
|
||||
}
|
||||
|
||||
// Ethereum path (no stored public key required)
|
||||
console.log(`🔐 Using Ethereum verification path`);
|
||||
return this.verifyEthereumSignature(message, signature, walletAddress);
|
||||
}
|
||||
}
|
||||
@ -89,6 +89,13 @@ export class ReOwnWalletService {
|
||||
// Convert message bytes to string for signing
|
||||
const messageString = new TextDecoder().decode(messageBytes);
|
||||
|
||||
console.log(`🔐 Wallet signing request:`, {
|
||||
walletType,
|
||||
requestedAddress: account.address,
|
||||
messageLength: messageString.length,
|
||||
messagePreview: messageString.slice(0, 100) + '...'
|
||||
});
|
||||
|
||||
try {
|
||||
// Access the adapter through the appKit instance
|
||||
// The adapter is available through the appKit's chainAdapters property
|
||||
@ -112,9 +119,15 @@ export class ReOwnWalletService {
|
||||
provider: provider as Provider
|
||||
});
|
||||
|
||||
console.log(`✅ Wallet signing completed:`, {
|
||||
requestedAddress: account.address,
|
||||
signatureLength: result.signature.length,
|
||||
signaturePrefix: result.signature.slice(0, 16) + '...'
|
||||
});
|
||||
|
||||
return result.signature;
|
||||
} catch (error) {
|
||||
console.error(`Error signing message with ${walletType} wallet:`, error);
|
||||
console.error(`❌ Error signing message with ${walletType} wallet:`, error);
|
||||
throw new Error(`Failed to sign message with ${walletType} wallet: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
@ -129,26 +142,87 @@ export class ReOwnWalletService {
|
||||
throw new Error(`No ${walletType} wallet connected`);
|
||||
}
|
||||
|
||||
console.log(`🔑 Starting key delegation creation:`, {
|
||||
walletType,
|
||||
accountAddress: account.address,
|
||||
duration
|
||||
});
|
||||
|
||||
// Generate a new browser keypair
|
||||
const keypair = this.keyDelegation.generateKeypair();
|
||||
|
||||
// Create delegation message with expiry
|
||||
const expiryHours = KeyDelegation.getDurationHours(duration);
|
||||
const expiryTimestamp = Date.now() + (expiryHours * 60 * 60 * 1000);
|
||||
const delegationMessage = this.keyDelegation.createDelegationMessage(
|
||||
let delegationMessage = this.keyDelegation.createDelegationMessage(
|
||||
keypair.publicKey,
|
||||
account.address,
|
||||
expiryTimestamp
|
||||
);
|
||||
|
||||
console.log(`📝 Delegation message created:`, {
|
||||
message: delegationMessage,
|
||||
browserPublicKey: keypair.publicKey.slice(0, 16) + '...',
|
||||
expiryTimestamp: new Date(expiryTimestamp).toISOString()
|
||||
});
|
||||
|
||||
const messageBytes = new TextEncoder().encode(delegationMessage);
|
||||
|
||||
// Sign the delegation message
|
||||
const signature = await this.signMessage(messageBytes, walletType);
|
||||
|
||||
console.log(`🔍 Wallet signing details:`, {
|
||||
originalMessage: delegationMessage,
|
||||
messageBytes: messageBytes.length,
|
||||
signature: signature,
|
||||
signatureLength: signature.length
|
||||
});
|
||||
|
||||
// Verify the signature matches the expected address
|
||||
let recoveredAddress: string | null = null;
|
||||
if (walletType === 'ethereum') {
|
||||
try {
|
||||
const { recoverMessageAddress } = await import('viem');
|
||||
|
||||
console.log(`🔍 Detailed signature analysis:`, {
|
||||
originalMessage: delegationMessage,
|
||||
signature: signature,
|
||||
signatureLength: signature.length,
|
||||
expectedAddress: account.address
|
||||
});
|
||||
|
||||
recoveredAddress = await recoverMessageAddress({
|
||||
message: delegationMessage,
|
||||
signature: signature as `0x${string}`
|
||||
});
|
||||
|
||||
console.log(`🔍 Signature verification check:`, {
|
||||
expectedAddress: account.address,
|
||||
recoveredAddress: recoveredAddress,
|
||||
addressesMatch: recoveredAddress.toLowerCase() === account.address.toLowerCase(),
|
||||
message: delegationMessage
|
||||
});
|
||||
|
||||
// Diagnostics only; do NOT mutate the message after signing
|
||||
console.log(`🔍 Additional verification:`, {
|
||||
recoveredAddressLowerCase: recoveredAddress.toLowerCase(),
|
||||
expectedAddressLowerCase: account.address.toLowerCase(),
|
||||
exactMatch: recoveredAddress === account.address,
|
||||
caseInsensitiveMatch: recoveredAddress.toLowerCase() === account.address.toLowerCase()
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`❌ Error verifying delegation signature:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`✅ Delegation signature received:`, {
|
||||
signatureLength: signature.length,
|
||||
signaturePrefix: signature.slice(0, 16) + '...'
|
||||
});
|
||||
|
||||
// Create and store the delegation
|
||||
const delegationInfo = this.keyDelegation.createDelegation(
|
||||
account.address,
|
||||
account.address, // store the original address used to build the message
|
||||
signature,
|
||||
keypair.publicKey,
|
||||
keypair.privateKey,
|
||||
@ -158,9 +232,11 @@ export class ReOwnWalletService {
|
||||
|
||||
this.keyDelegation.storeDelegation(delegationInfo);
|
||||
|
||||
console.log(`🎉 Key delegation created and stored successfully`);
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(`Error creating key delegation for ${walletType}:`, error);
|
||||
console.error(`❌ Error creating key delegation for ${walletType}:`, error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,11 +5,11 @@ import { MessageType } from "./types";
|
||||
* Content topics for different message types
|
||||
*/
|
||||
export const CONTENT_TOPICS: Record<MessageType, string> = {
|
||||
[MessageType.CELL]: '/opchan/1/cell/proto',
|
||||
[MessageType.POST]: '/opchan/1/post/proto',
|
||||
[MessageType.COMMENT]: '/opchan/1/comment/proto',
|
||||
[MessageType.VOTE]: '/opchan/1/vote/proto',
|
||||
[MessageType.MODERATE]: '/opchan/1/moderate/proto'
|
||||
[MessageType.CELL]: '/opcxzzhzaxsn221-aß/1/cell/proto',
|
||||
[MessageType.POST]: '/opchan-x/1/post/proto',
|
||||
[MessageType.COMMENT]: '/opchan-x/1/comment/proto',
|
||||
[MessageType.VOTE]: '/opchan-x/1/vote/proto',
|
||||
[MessageType.MODERATE]: '/opchan-x/1/moderate/proto'
|
||||
};
|
||||
|
||||
export const NETWORK_CONFIG: NetworkConfig = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user