feat(co-sign): add invite code display in CoSignSession page

- Add invite_code retrieval in GetSignSessionStatus (backend)
- Add inviteCode to cosign:getSessionStatus response (frontend IPC)
- Add inviteCode to SessionState and display UI in CoSignSession

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-31 01:37:11 -08:00
parent cfbda7bbc7
commit 4d65b8dd83
3 changed files with 40 additions and 0 deletions

View File

@ -616,6 +616,13 @@ func (h *CoManagedHTTPHandler) GetSignSessionStatus(c *gin.Context) {
return
}
// Get invite_code from database
var inviteCode string
if h.db != nil {
row := h.db.QueryRowContext(ctx, `SELECT invite_code FROM mpc_sessions WHERE id = $1`, sessionID)
row.Scan(&inviteCode) // Ignore error, invite_code is optional
}
result := gin.H{
"session_id": sessionID,
"status": resp.Status,
@ -626,6 +633,11 @@ func (h *CoManagedHTTPHandler) GetSignSessionStatus(c *gin.Context) {
"total_parties": resp.TotalParties,
}
// Add invite_code if available
if inviteCode != "" {
result["invite_code"] = inviteCode
}
// Add signature if sign completed
if resp.SessionType == "sign" && len(resp.Signature) > 0 {
result["signature"] = hex.EncodeToString(resp.Signature)

View File

@ -1839,6 +1839,7 @@ function setupIpcHandlers() {
sessionId: result?.session_id,
status: result?.status,
joinedCount: result?.joined_count,
inviteCode: (result as { invite_code?: string })?.invite_code || '',
threshold: {
t: result?.threshold_t || activeCoSignSession?.threshold?.t || 0,
n: result?.threshold_n || activeCoSignSession?.threshold?.n || 0,

View File

@ -26,6 +26,7 @@ interface SessionState {
sessionId: string;
walletName: string;
messageHash: string;
inviteCode?: string;
threshold: { t: number; n: number };
status: 'waiting' | 'ready' | 'processing' | 'completed' | 'failed';
participants: Participant[];
@ -59,6 +60,7 @@ export default function CoSignSession() {
sessionId: result.session.sessionId || sessionId,
walletName: result.session.walletName || '',
messageHash: result.session.messageHash || '',
inviteCode: result.session.inviteCode || '',
threshold: result.session.threshold || { t: 0, n: 0 },
status: mapStatus(result.session.status),
participants: (result.session.participants || []).map(p => ({
@ -341,6 +343,31 @@ export default function CoSignSession() {
</div>
<div className={styles.content}>
{/* 邀请码 - 等待状态时显示 */}
{session.inviteCode && session.status === 'waiting' && (
<div className={styles.section}>
<h3 className={styles.sectionTitle}></h3>
<div className={styles.publicKeyWrapper}>
<code className={styles.publicKey}>{session.inviteCode}</code>
<button
className={styles.copyButton}
onClick={async () => {
try {
await navigator.clipboard.writeText(session.inviteCode!);
} catch (err) {
console.error('Failed to copy:', err);
}
}}
>
</button>
</div>
<p style={{ fontSize: '12px', color: 'var(--text-secondary)', marginTop: 'var(--spacing-xs)' }}>
使
</p>
</div>
)}
{/* 消息哈希 */}
{session.messageHash && (
<div className={styles.section}>