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:
parent
cfbda7bbc7
commit
4d65b8dd83
|
|
@ -616,6 +616,13 @@ func (h *CoManagedHTTPHandler) GetSignSessionStatus(c *gin.Context) {
|
||||||
return
|
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{
|
result := gin.H{
|
||||||
"session_id": sessionID,
|
"session_id": sessionID,
|
||||||
"status": resp.Status,
|
"status": resp.Status,
|
||||||
|
|
@ -626,6 +633,11 @@ func (h *CoManagedHTTPHandler) GetSignSessionStatus(c *gin.Context) {
|
||||||
"total_parties": resp.TotalParties,
|
"total_parties": resp.TotalParties,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add invite_code if available
|
||||||
|
if inviteCode != "" {
|
||||||
|
result["invite_code"] = inviteCode
|
||||||
|
}
|
||||||
|
|
||||||
// Add signature if sign completed
|
// Add signature if sign completed
|
||||||
if resp.SessionType == "sign" && len(resp.Signature) > 0 {
|
if resp.SessionType == "sign" && len(resp.Signature) > 0 {
|
||||||
result["signature"] = hex.EncodeToString(resp.Signature)
|
result["signature"] = hex.EncodeToString(resp.Signature)
|
||||||
|
|
|
||||||
|
|
@ -1839,6 +1839,7 @@ function setupIpcHandlers() {
|
||||||
sessionId: result?.session_id,
|
sessionId: result?.session_id,
|
||||||
status: result?.status,
|
status: result?.status,
|
||||||
joinedCount: result?.joined_count,
|
joinedCount: result?.joined_count,
|
||||||
|
inviteCode: (result as { invite_code?: string })?.invite_code || '',
|
||||||
threshold: {
|
threshold: {
|
||||||
t: result?.threshold_t || activeCoSignSession?.threshold?.t || 0,
|
t: result?.threshold_t || activeCoSignSession?.threshold?.t || 0,
|
||||||
n: result?.threshold_n || activeCoSignSession?.threshold?.n || 0,
|
n: result?.threshold_n || activeCoSignSession?.threshold?.n || 0,
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ interface SessionState {
|
||||||
sessionId: string;
|
sessionId: string;
|
||||||
walletName: string;
|
walletName: string;
|
||||||
messageHash: string;
|
messageHash: string;
|
||||||
|
inviteCode?: string;
|
||||||
threshold: { t: number; n: number };
|
threshold: { t: number; n: number };
|
||||||
status: 'waiting' | 'ready' | 'processing' | 'completed' | 'failed';
|
status: 'waiting' | 'ready' | 'processing' | 'completed' | 'failed';
|
||||||
participants: Participant[];
|
participants: Participant[];
|
||||||
|
|
@ -59,6 +60,7 @@ export default function CoSignSession() {
|
||||||
sessionId: result.session.sessionId || sessionId,
|
sessionId: result.session.sessionId || sessionId,
|
||||||
walletName: result.session.walletName || '',
|
walletName: result.session.walletName || '',
|
||||||
messageHash: result.session.messageHash || '',
|
messageHash: result.session.messageHash || '',
|
||||||
|
inviteCode: result.session.inviteCode || '',
|
||||||
threshold: result.session.threshold || { t: 0, n: 0 },
|
threshold: result.session.threshold || { t: 0, n: 0 },
|
||||||
status: mapStatus(result.session.status),
|
status: mapStatus(result.session.status),
|
||||||
participants: (result.session.participants || []).map(p => ({
|
participants: (result.session.participants || []).map(p => ({
|
||||||
|
|
@ -341,6 +343,31 @@ export default function CoSignSession() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.content}>
|
<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 && (
|
{session.messageHash && (
|
||||||
<div className={styles.section}>
|
<div className={styles.section}>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue