fix(scripts): 添加 JWT 认证支持
mpc-system account-service 需要 JWT 认证,脚本需要: - 添加 --jwt-secret 参数或从 MPC_JWT_SECRET 环境变量读取 - 使用 openssl 生成 HS256 JWT token - 所有 API 请求添加 Authorization: Bearer header 用法: export MPC_JWT_SECRET='your_secret' ./init-hot-wallet.sh --username rwadurian-system-hot-wallet-01 --threshold-n 3 --threshold-t 2 🤖 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
c0e6e1f620
commit
93c658d914
|
|
@ -10,11 +10,13 @@
|
|||
# 2. mpc-system session-coordinator 和 server-party 已启动
|
||||
# 3. jq 已安装 (用于解析 JSON)
|
||||
# 4. curl 已安装
|
||||
# 5. 环境变量 MPC_JWT_SECRET 已设置(或通过 --jwt-secret 参数传入)
|
||||
#
|
||||
# 使用方法:
|
||||
# ./init-hot-wallet.sh --username <wallet-name> --threshold-n <n> --threshold-t <t>
|
||||
# ./init-hot-wallet.sh --username <wallet-name> --threshold-n <n> --threshold-t <t> [--jwt-secret <secret>]
|
||||
#
|
||||
# 示例:
|
||||
# export MPC_JWT_SECRET="your_jwt_secret_key"
|
||||
# ./init-hot-wallet.sh --username rwadurian-system-hot-wallet-01 --threshold-n 3 --threshold-t 2
|
||||
#
|
||||
# =============================================================================
|
||||
|
|
@ -34,6 +36,7 @@ USERNAME=""
|
|||
THRESHOLD_N=3
|
||||
THRESHOLD_T=2
|
||||
MPC_HOST="http://localhost:4000"
|
||||
JWT_SECRET="${MPC_JWT_SECRET:-}"
|
||||
VERBOSE=true
|
||||
|
||||
# 日志函数
|
||||
|
|
@ -59,6 +62,28 @@ log_debug() {
|
|||
fi
|
||||
}
|
||||
|
||||
# 生成 JWT Token (简化版,用于 MPC 系统认证)
|
||||
# 使用 openssl + base64 生成 HS256 JWT
|
||||
generate_jwt_token() {
|
||||
local secret="$1"
|
||||
local now=$(date +%s)
|
||||
local exp=$((now + 86400)) # 24小时后过期
|
||||
local jti=$(cat /proc/sys/kernel/random/uuid 2>/dev/null || uuidgen 2>/dev/null || echo "$(date +%s)-$$")
|
||||
|
||||
# JWT Header
|
||||
local header='{"alg":"HS256","typ":"JWT"}'
|
||||
local header_b64=$(echo -n "$header" | base64 -w0 | tr '+/' '-_' | tr -d '=')
|
||||
|
||||
# JWT Payload
|
||||
local payload="{\"jti\":\"$jti\",\"iss\":\"init-script\",\"sub\":\"system\",\"party_id\":\"init-script\",\"token_type\":\"access\",\"iat\":$now,\"nbf\":$now,\"exp\":$exp}"
|
||||
local payload_b64=$(echo -n "$payload" | base64 -w0 | tr '+/' '-_' | tr -d '=')
|
||||
|
||||
# JWT Signature (HMAC-SHA256)
|
||||
local signature=$(echo -n "${header_b64}.${payload_b64}" | openssl dgst -sha256 -hmac "$secret" -binary | base64 -w0 | tr '+/' '-_' | tr -d '=')
|
||||
|
||||
echo "${header_b64}.${payload_b64}.${signature}"
|
||||
}
|
||||
|
||||
# 检查依赖
|
||||
check_dependencies() {
|
||||
log_info "检查依赖..."
|
||||
|
|
@ -78,6 +103,12 @@ check_dependencies() {
|
|||
fi
|
||||
log_debug "✓ jq 已安装"
|
||||
|
||||
if ! command -v openssl &> /dev/null; then
|
||||
log_error "openssl 未安装,请先安装 openssl"
|
||||
exit 1
|
||||
fi
|
||||
log_debug "✓ openssl 已安装"
|
||||
|
||||
log_success "依赖检查通过"
|
||||
}
|
||||
|
||||
|
|
@ -129,9 +160,13 @@ parse_args() {
|
|||
THRESHOLD_T="$2"
|
||||
shift 2
|
||||
;;
|
||||
--jwt-secret)
|
||||
JWT_SECRET="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
log_error "未知参数: $1"
|
||||
echo "用法: ./init-hot-wallet.sh --username <name> --threshold-n <n> --threshold-t <t>"
|
||||
echo "用法: ./init-hot-wallet.sh --username <name> --threshold-n <n> --threshold-t <t> [--jwt-secret <secret>]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
@ -143,11 +178,20 @@ validate_params() {
|
|||
if [ -z "$USERNAME" ]; then
|
||||
log_error "用户名不能为空"
|
||||
echo ""
|
||||
echo "用法: ./init-hot-wallet.sh --username <name> --threshold-n <n> --threshold-t <t>"
|
||||
echo "用法: ./init-hot-wallet.sh --username <name> --threshold-n <n> --threshold-t <t> [--jwt-secret <secret>]"
|
||||
echo "示例: ./init-hot-wallet.sh --username rwadurian-system-hot-wallet-01 --threshold-n 3 --threshold-t 2"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JWT_SECRET" ]; then
|
||||
log_error "JWT_SECRET 不能为空"
|
||||
echo ""
|
||||
echo "请通过以下方式之一提供 JWT_SECRET:"
|
||||
echo " 1. 设置环境变量: export MPC_JWT_SECRET='your_secret'"
|
||||
echo " 2. 命令行参数: --jwt-secret 'your_secret'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$THRESHOLD_N" -lt 2 ]; then
|
||||
log_error "总 party 数量 (threshold-n) 必须 >= 2"
|
||||
exit 1
|
||||
|
|
@ -164,6 +208,10 @@ validate_params() {
|
|||
create_keygen_session() {
|
||||
log_info "创建 Keygen 会话..."
|
||||
|
||||
# 生成 JWT Token
|
||||
local jwt_token=$(generate_jwt_token "$JWT_SECRET")
|
||||
log_debug "JWT Token: ${jwt_token:0:50}..."
|
||||
|
||||
local url="$MPC_HOST/api/v1/mpc/keygen"
|
||||
# mpc-system 使用 snake_case: threshold_n, threshold_t, require_delegate
|
||||
local payload="{
|
||||
|
|
@ -178,6 +226,7 @@ create_keygen_session() {
|
|||
|
||||
KEYGEN_RESPONSE=$(curl -s -X POST "$url" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $jwt_token" \
|
||||
-d "$payload" \
|
||||
--connect-timeout 30 \
|
||||
--max-time 60)
|
||||
|
|
@ -220,6 +269,9 @@ wait_for_keygen() {
|
|||
log_info "等待 Keygen 完成 (最多 6 分钟)..."
|
||||
echo ""
|
||||
|
||||
# 生成 JWT Token
|
||||
local jwt_token=$(generate_jwt_token "$JWT_SECRET")
|
||||
|
||||
local max_attempts=180 # 6 分钟 (每 2 秒轮询一次)
|
||||
local attempt=0
|
||||
local last_status=""
|
||||
|
|
@ -229,7 +281,7 @@ wait_for_keygen() {
|
|||
while [ $attempt -lt $max_attempts ]; do
|
||||
# mpc-system 状态查询 API: /api/v1/mpc/sessions/{sessionId}
|
||||
local url="$MPC_HOST/api/v1/mpc/sessions/$SESSION_ID"
|
||||
STATUS_RESPONSE=$(curl -s -X GET "$url" --connect-timeout 10)
|
||||
STATUS_RESPONSE=$(curl -s -X GET "$url" -H "Authorization: Bearer $jwt_token" --connect-timeout 10)
|
||||
|
||||
log_debug "轮询响应: $STATUS_RESPONSE"
|
||||
|
||||
|
|
@ -284,8 +336,9 @@ get_public_key() {
|
|||
|
||||
if [ -z "$PUBLIC_KEY" ] || [ "$PUBLIC_KEY" == "null" ]; then
|
||||
# 再次获取状态以确保拿到公钥
|
||||
local jwt_token=$(generate_jwt_token "$JWT_SECRET")
|
||||
local url="$MPC_HOST/api/v1/mpc/sessions/$SESSION_ID"
|
||||
STATUS_RESPONSE=$(curl -s -X GET "$url")
|
||||
STATUS_RESPONSE=$(curl -s -X GET "$url" -H "Authorization: Bearer $jwt_token")
|
||||
PUBLIC_KEY=$(echo "$STATUS_RESPONSE" | jq -r '.public_key')
|
||||
fi
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue