Revert "fix(mpc-service): don't block startup on Kafka consumer rebalance"
This reverts commit c924d3aad2.
This commit is contained in:
parent
c924d3aad2
commit
429f8d5991
|
|
@ -1,63 +1,8 @@
|
|||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(__NEW_LINE__ echo \"=== Test /api/v1/referral/me (referral-service) ===\")",
|
||||
"Bash(git -C \"c:\\Users\\dong\\Desktop\\rwadurian\" push)",
|
||||
"Bash(__NEW_LINE__ echo \"=== Test /api/v1/authorizations/my (authorization-service on port 3002) ===\")",
|
||||
"Bash(__NEW_LINE__ echo \"=== Test /api/v1/authorizations/my (authorization-service on port 3009) ===\")",
|
||||
"Bash(backend/api-gateway/kong.yml )",
|
||||
"Bash(frontend/mobile-app/lib/core/constants/api_endpoints.dart )",
|
||||
"Bash(frontend/mobile-app/lib/core/di/injection_container.dart )",
|
||||
"Bash(frontend/mobile-app/lib/core/services/referral_service.dart )",
|
||||
"Bash(frontend/mobile-app/lib/core/services/authorization_service.dart )",
|
||||
"Bash(frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart )",
|
||||
"Bash(backend/services/authorization-service/package.json )",
|
||||
"Bash(backend/services/authorization-service/package-lock.json )",
|
||||
"Bash(backend/services/authorization-service/src/shared/strategies/jwt.strategy.ts )",
|
||||
"Bash(backend/services/authorization-service/src/infrastructure/persistence/repositories/system-account.repository.impl.ts)",
|
||||
"Bash(DATABASE_URL=\"postgresql://rwauser:rwapass123@localhost:5432/rwa_authorization\" npx prisma migrate:*)",
|
||||
"Bash(backend/services/authorization-service/.gitignore )",
|
||||
"Bash(backend/services/authorization-service/prisma/migrations/00000000000000_init/migration.sql )",
|
||||
"Bash(git fetch:*)",
|
||||
"Bash(backend/services/blockchain-service/package.json )",
|
||||
"Bash(backend/services/blockchain-service/package-lock.json )",
|
||||
"Bash(backend/services/blockchain-service/src/api/api.module.ts )",
|
||||
"Bash(backend/services/blockchain-service/src/api/controllers/index.ts )",
|
||||
"Bash(backend/services/blockchain-service/src/api/controllers/deposit.controller.ts )",
|
||||
"Bash(backend/services/blockchain-service/src/shared/index.ts )",
|
||||
"Bash(backend/services/blockchain-service/src/shared/decorators/ )",
|
||||
"Bash(backend/services/blockchain-service/src/shared/guards/ )",
|
||||
"Bash(backend/services/blockchain-service/src/shared/strategies/ )",
|
||||
"Bash(backend/services/wallet-service/src/api/api.module.ts )",
|
||||
"Bash(backend/services/wallet-service/src/infrastructure/kafka/ )",
|
||||
"Bash(backend/services/wallet-service/src/application/event-handlers/ )",
|
||||
"Bash(backend/services/docker-compose.yml )",
|
||||
"Bash(frontend/mobile-app/lib/core/services/deposit_service.dart)",
|
||||
"Bash(backend/services/authorization-service/prisma/schema.prisma )",
|
||||
"Bash(backend/services/authorization-service/src/application/services/ )",
|
||||
"Bash(backend/services/authorization-service/src/domain/ )",
|
||||
"Bash(backend/services/authorization-service/src/infrastructure/persistence/repositories/ )",
|
||||
"Bash(backend/services/planting-service/src/application/services/planting-application.service.ts )",
|
||||
"Bash(backend/services/planting-service/src/domain/services/fund-allocation.service.ts )",
|
||||
"Bash(backend/services/planting-service/src/infrastructure/external/ )",
|
||||
"Bash(backend/services/planting-service/src/infrastructure/infrastructure.module.ts )",
|
||||
"Bash(backend/services/planting-service/src/infrastructure/persistence/prisma/prisma.service.ts )",
|
||||
"Bash(backend/services/planting-service/src/infrastructure/persistence/unit-of-work.ts )",
|
||||
"Bash(backend/services/referral-service/src/modules/api.module.ts )",
|
||||
"Bash(backend/services/reward-service/src/infrastructure/external/authorization-service/authorization-service.client.ts )",
|
||||
"Bash(backend/services/wallet-service/package.json )",
|
||||
"Bash(backend/services/wallet-service/prisma/schema.prisma )",
|
||||
"Bash(backend/services/wallet-service/src/)",
|
||||
"Bash(git status:*)",
|
||||
"Bash(git check-ignore:*)",
|
||||
"Bash(docker inspect:*)",
|
||||
"Bash(python -m json.tool:*)",
|
||||
"Bash(docker logs:*)",
|
||||
"Bash(curl:*)",
|
||||
"Bash(git add:*)",
|
||||
"Bash(git commit:*)",
|
||||
"Bash(git push)",
|
||||
"Bash(cat:*)"
|
||||
"Bash(git -C \"c:\\Users\\dong\\Desktop\\rwadurian\" commit -m \"$(cat <<''EOF''\nfix(mobile-app): skip backup mnemonic page for MPC wallet mode\n\n- Fix mnemonic parsing: empty string \"\" now correctly becomes empty list\n- MPC mode (no mnemonic) skips backup page and navigates directly to home\n- Apply fix to both initial load and polling logic\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nEOF\n)\")",
|
||||
"Bash(npx prisma:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
|
|
|||
|
|
@ -1,102 +0,0 @@
|
|||
# =============================================================================
|
||||
# MinIO Object Storage - 环境配置
|
||||
# =============================================================================
|
||||
#
|
||||
# 部署位置: 与 Kong, Nginx 同一服务器 (Server A: 192.168.1.100)
|
||||
# 用途: 用户头像、文档、资源文件的对象存储
|
||||
#
|
||||
# 网络拓扑:
|
||||
# ┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
# │ Server A (192.168.1.100) - Gateway & Storage │
|
||||
# ├─────────────────────────────────────────────────────────────────────────────┤
|
||||
# │ Nginx :80/443 - 反向代理 (SSL 终止) │
|
||||
# │ Kong :8000 - API 网关 │
|
||||
# │ MinIO API :9000 - S3 兼容 API │
|
||||
# │ MinIO Console:9001 - Web 管理控制台 │
|
||||
# └─────────────────────────────────────────────────────────────────────────────┘
|
||||
#
|
||||
# 设置步骤:
|
||||
# 1. 复制配置: cp .env.example .env
|
||||
# 2. 修改密码: 必须修改 MINIO_ROOT_PASSWORD
|
||||
# 3. 创建数据目录: sudo mkdir -p /data/minio && sudo chown -R 1000:1000 /data/minio
|
||||
# 4. 启动服务: ./deploy.sh up
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
# =============================================================================
|
||||
# MinIO 认证配置
|
||||
# =============================================================================
|
||||
# 管理员用户名 (至少 3 个字符)
|
||||
MINIO_ROOT_USER=admin
|
||||
|
||||
# 管理员密码 (至少 8 个字符)
|
||||
# ⚠️ 安全警告: 生产环境必须修改此密码!
|
||||
# 生成安全密码: openssl rand -base64 32
|
||||
MINIO_ROOT_PASSWORD=change_me_to_secure_password
|
||||
|
||||
# =============================================================================
|
||||
# MinIO 服务端口
|
||||
# =============================================================================
|
||||
# S3 API 端口 - 应用程序通过此端口上传下载文件
|
||||
MINIO_API_PORT=9000
|
||||
|
||||
# Web 控制台端口 - 管理员通过此端口管理 MinIO
|
||||
MINIO_CONSOLE_PORT=9001
|
||||
|
||||
# =============================================================================
|
||||
# MinIO 服务器配置
|
||||
# =============================================================================
|
||||
# 区域设置 (用于 S3 兼容性)
|
||||
MINIO_REGION=cn-east-1
|
||||
|
||||
# 控制台外部访问 URL (用于 Nginx 反向代理场景)
|
||||
# 内网访问: http://192.168.1.100:9001
|
||||
# 外网访问: https://minio.szaiai.com
|
||||
MINIO_CONSOLE_URL=http://localhost:9001
|
||||
|
||||
# =============================================================================
|
||||
# 数据存储配置
|
||||
# =============================================================================
|
||||
# 数据存储路径 (确保有足够的磁盘空间)
|
||||
# 建议使用独立的数据盘
|
||||
MINIO_DATA_PATH=/data/minio
|
||||
|
||||
# =============================================================================
|
||||
# 默认存储桶配置
|
||||
# =============================================================================
|
||||
# 用户头像存储桶 (公开读取)
|
||||
BUCKET_AVATARS=avatars
|
||||
|
||||
# 用户文档存储桶 (需要认证)
|
||||
BUCKET_DOCUMENTS=documents
|
||||
|
||||
# 应用资源文件存储桶 (公开读取)
|
||||
BUCKET_RESOURCES=resources
|
||||
|
||||
# 备份文件存储桶 (私有)
|
||||
BUCKET_BACKUPS=backups
|
||||
|
||||
# =============================================================================
|
||||
# 服务间通信配置 (供后端服务使用)
|
||||
# =============================================================================
|
||||
# MinIO 内部端点 (后端服务访问)
|
||||
# 在同一服务器: http://localhost:9000
|
||||
# 在不同服务器: http://192.168.1.100:9000
|
||||
MINIO_ENDPOINT=http://localhost:9000
|
||||
|
||||
# 公开访问 URL (前端直接访问静态资源)
|
||||
# 通过 Nginx 代理: https://cdn.szaiai.com
|
||||
# 直接访问: http://192.168.1.100:9000
|
||||
MINIO_PUBLIC_URL=http://localhost:9000
|
||||
|
||||
# =============================================================================
|
||||
# 网络配置
|
||||
# =============================================================================
|
||||
# 本机 IP (供其他服务连接)
|
||||
MINIO_HOST_IP=192.168.1.100
|
||||
|
||||
# =============================================================================
|
||||
# 日志配置
|
||||
# =============================================================================
|
||||
# 日志级别: DEBUG, INFO, WARNING, ERROR
|
||||
MINIO_LOG_LEVEL=INFO
|
||||
|
|
@ -110,6 +110,10 @@ services:
|
|||
volumes:
|
||||
minio_data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
o: bind
|
||||
device: ${MINIO_DATA_PATH:-/data/minio}
|
||||
|
||||
# =============================================================================
|
||||
# Networks
|
||||
|
|
|
|||
|
|
@ -100,25 +100,6 @@ MPC_ACCOUNT_SERVICE_URL=http://192.168.1.111:4000
|
|||
# SECURITY: Generate with: openssl rand -base64 48
|
||||
MPC_JWT_SECRET=change_this_jwt_secret_key_to_random_value_min_32_chars
|
||||
|
||||
# =============================================================================
|
||||
# Blockchain Network Configuration
|
||||
# =============================================================================
|
||||
# Network mode: mainnet or testnet
|
||||
# - mainnet: Production networks (KAVA mainnet, BSC mainnet)
|
||||
# - testnet: Test networks (KAVA testnet, BSC testnet)
|
||||
NETWORK_MODE=mainnet
|
||||
|
||||
# BSC Testnet faucet: https://testnet.bnbchain.org/faucet-smart
|
||||
# KAVA Testnet faucet: https://faucet.kava.io
|
||||
|
||||
# Optional: Override specific chain settings
|
||||
# KAVA_RPC_URL=https://evm.kava.io
|
||||
# KAVA_CHAIN_ID=2222
|
||||
# KAVA_USDT_CONTRACT=0x919C1c267BC06a7039e03fcc2eF738525769109c
|
||||
# BSC_RPC_URL=https://bsc-dataseed.binance.org
|
||||
# BSC_CHAIN_ID=56
|
||||
# BSC_USDT_CONTRACT=0x55d398326f99059fF775485246999027B3197955
|
||||
|
||||
# =============================================================================
|
||||
# MinIO Object Storage (Server A: 192.168.1.100)
|
||||
# =============================================================================
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ export class EventConsumerStarterService implements OnApplicationBootstrap {
|
|||
|
||||
constructor(private readonly eventConsumer: EventConsumerService) {}
|
||||
|
||||
onApplicationBootstrap() {
|
||||
// Don't await - consumer.run() blocks until rebalance completes
|
||||
// Let it run in background while HTTP server starts immediately
|
||||
this.eventConsumer.startConsuming().catch((error) => {
|
||||
async onApplicationBootstrap() {
|
||||
try {
|
||||
await this.eventConsumer.startConsuming();
|
||||
this.logger.log('MPC event consumers started successfully');
|
||||
} catch (error) {
|
||||
this.logger.error('Failed to start MPC event consumers', error);
|
||||
});
|
||||
this.logger.log('MPC event consumers starting in background');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,7 +247,6 @@
|
|||
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
|
|
|
|||
|
|
@ -1,168 +0,0 @@
|
|||
# =============================================================================
|
||||
# E2E Test: Create Account and Wait for Wallet Ready (PowerShell)
|
||||
# =============================================================================
|
||||
#
|
||||
# This script simulates the mobile app flow:
|
||||
# 1. Call POST /user/auto-create to create a new account
|
||||
# 2. Poll GET /user/wallet until wallet is ready (has mnemonic and 3 addresses)
|
||||
#
|
||||
# Usage: .\e2e_wallet_test.ps1 [-BaseUrl "http://localhost:3000/api/v1"]
|
||||
# =============================================================================
|
||||
|
||||
param(
|
||||
[string]$BaseUrl = "http://localhost:3000/api/v1"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# Configuration
|
||||
$DeviceId = "test-device-$(Get-Date -Format 'yyyyMMddHHmmss')"
|
||||
$MaxRetries = 60
|
||||
$RetryInterval = 5
|
||||
|
||||
Write-Host "=============================================="
|
||||
Write-Host "E2E Wallet Creation Test"
|
||||
Write-Host "=============================================="
|
||||
Write-Host "Base URL: $BaseUrl"
|
||||
Write-Host "Device ID: $DeviceId"
|
||||
Write-Host "=============================================="
|
||||
Write-Host ""
|
||||
|
||||
# Step 1: Create Account
|
||||
Write-Host "[Step 1] Creating account..."
|
||||
|
||||
$CreateBody = @{
|
||||
deviceId = $DeviceId
|
||||
deviceName = @{
|
||||
brand = "Test"
|
||||
model = "E2E-Device"
|
||||
platform = "android"
|
||||
osVersion = "14"
|
||||
}
|
||||
} | ConvertTo-Json -Depth 3
|
||||
|
||||
try {
|
||||
$CreateResponse = Invoke-RestMethod -Uri "$BaseUrl/user/auto-create" `
|
||||
-Method Post `
|
||||
-ContentType "application/json" `
|
||||
-Body $CreateBody
|
||||
} catch {
|
||||
Write-Host "❌ Failed to create account!" -ForegroundColor Red
|
||||
Write-Host "Error: $($_.Exception.Message)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if (-not $CreateResponse.success) {
|
||||
Write-Host "❌ Failed to create account!" -ForegroundColor Red
|
||||
Write-Host "Error: $($CreateResponse.message)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$AccessToken = $CreateResponse.data.accessToken
|
||||
$UserSerialNum = $CreateResponse.data.userSerialNum
|
||||
$Username = $CreateResponse.data.username
|
||||
$ReferralCode = $CreateResponse.data.referralCode
|
||||
|
||||
Write-Host "✅ Account created successfully!" -ForegroundColor Green
|
||||
Write-Host " User Serial Number: $UserSerialNum"
|
||||
Write-Host " Username: $Username"
|
||||
Write-Host " Referral Code: $ReferralCode"
|
||||
Write-Host ""
|
||||
|
||||
# Step 2: Poll Wallet Status
|
||||
Write-Host "[Step 2] Polling wallet status..."
|
||||
Write-Host " Max retries: $MaxRetries"
|
||||
Write-Host " Retry interval: ${RetryInterval}s"
|
||||
Write-Host ""
|
||||
|
||||
$Headers = @{
|
||||
"Authorization" = "Bearer $AccessToken"
|
||||
"Content-Type" = "application/json"
|
||||
}
|
||||
|
||||
$WalletReady = $false
|
||||
$WalletResponse = $null
|
||||
|
||||
for ($i = 1; $i -le $MaxRetries; $i++) {
|
||||
try {
|
||||
$WalletResponse = Invoke-RestMethod -Uri "$BaseUrl/user/wallet" `
|
||||
-Method Get `
|
||||
-Headers $Headers
|
||||
} catch {
|
||||
Write-Host "[Attempt $i/$MaxRetries] Error: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
Start-Sleep -Seconds $RetryInterval
|
||||
continue
|
||||
}
|
||||
|
||||
$WalletStatus = $WalletResponse.data.status
|
||||
|
||||
Write-Host "[Attempt $i/$MaxRetries] Wallet status: $WalletStatus"
|
||||
|
||||
if ($WalletStatus -eq "ready") {
|
||||
$WalletReady = $true
|
||||
break
|
||||
} elseif ($WalletStatus -eq "failed") {
|
||||
Write-Host "❌ Wallet generation failed!" -ForegroundColor Red
|
||||
Write-Host "Error: $($WalletResponse.data.error)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Still generating, wait and retry
|
||||
Start-Sleep -Seconds $RetryInterval
|
||||
}
|
||||
|
||||
if (-not $WalletReady) {
|
||||
Write-Host "❌ Timeout waiting for wallet to be ready!" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=============================================="
|
||||
Write-Host "✅ WALLET READY!" -ForegroundColor Green
|
||||
Write-Host "=============================================="
|
||||
Write-Host ""
|
||||
|
||||
# Extract wallet data
|
||||
$Mnemonic = $WalletResponse.data.mnemonic
|
||||
$KavaAddress = $WalletResponse.data.walletAddresses.kava
|
||||
$DstAddress = $WalletResponse.data.walletAddresses.dst
|
||||
$BscAddress = $WalletResponse.data.walletAddresses.bsc
|
||||
|
||||
Write-Host "📝 Mnemonic (12 words):" -ForegroundColor Cyan
|
||||
Write-Host " $Mnemonic"
|
||||
Write-Host ""
|
||||
Write-Host "💰 Wallet Addresses:" -ForegroundColor Cyan
|
||||
Write-Host " KAVA: $KavaAddress"
|
||||
Write-Host " DST: $DstAddress"
|
||||
Write-Host " BSC: $BscAddress"
|
||||
Write-Host ""
|
||||
Write-Host "=============================================="
|
||||
Write-Host "Test completed successfully!" -ForegroundColor Green
|
||||
Write-Host "=============================================="
|
||||
|
||||
# Validate results
|
||||
if ([string]::IsNullOrEmpty($Mnemonic)) {
|
||||
Write-Host "⚠️ Warning: Mnemonic is empty" -ForegroundColor Yellow
|
||||
} else {
|
||||
$WordCount = ($Mnemonic -split '\s+').Count
|
||||
if ($WordCount -ne 12) {
|
||||
Write-Host "⚠️ Warning: Mnemonic word count is $WordCount (expected 12)" -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrEmpty($KavaAddress) -or [string]::IsNullOrEmpty($DstAddress) -or [string]::IsNullOrEmpty($BscAddress)) {
|
||||
Write-Host "⚠️ Warning: Some wallet addresses are missing" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# Return summary object
|
||||
return @{
|
||||
UserSerialNum = $UserSerialNum
|
||||
Username = $Username
|
||||
ReferralCode = $ReferralCode
|
||||
Mnemonic = $Mnemonic
|
||||
WalletAddresses = @{
|
||||
Kava = $KavaAddress
|
||||
Dst = $DstAddress
|
||||
Bsc = $BscAddress
|
||||
}
|
||||
}
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# E2E Test: Create Account and Wait for Wallet Ready
|
||||
# =============================================================================
|
||||
#
|
||||
# This script simulates the mobile app flow:
|
||||
# 1. Call POST /user/auto-create to create a new account
|
||||
# 2. Poll GET /user/wallet until wallet is ready (has mnemonic and 3 addresses)
|
||||
#
|
||||
# Usage: ./e2e_wallet_test.sh [BASE_URL]
|
||||
# Default BASE_URL: http://localhost:3000/api/v1
|
||||
# =============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
BASE_URL="${1:-http://localhost:3000/api/v1}"
|
||||
DEVICE_ID="test-device-$(date +%s)"
|
||||
MAX_RETRIES=60
|
||||
RETRY_INTERVAL=5
|
||||
|
||||
echo "=============================================="
|
||||
echo "E2E Wallet Creation Test"
|
||||
echo "=============================================="
|
||||
echo "Base URL: $BASE_URL"
|
||||
echo "Device ID: $DEVICE_ID"
|
||||
echo "=============================================="
|
||||
echo ""
|
||||
|
||||
# Step 1: Create Account
|
||||
echo "[Step 1] Creating account..."
|
||||
CREATE_RESPONSE=$(curl -s -X POST "${BASE_URL}/user/auto-create" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"deviceId\": \"${DEVICE_ID}\",
|
||||
\"deviceName\": {
|
||||
\"brand\": \"Test\",
|
||||
\"model\": \"E2E-Device\",
|
||||
\"platform\": \"android\",
|
||||
\"osVersion\": \"14\"
|
||||
}
|
||||
}")
|
||||
|
||||
echo "Response: $CREATE_RESPONSE"
|
||||
echo ""
|
||||
|
||||
# Parse response
|
||||
SUCCESS=$(echo "$CREATE_RESPONSE" | jq -r '.success // false')
|
||||
if [ "$SUCCESS" != "true" ]; then
|
||||
echo "❌ Failed to create account!"
|
||||
echo "Error: $(echo "$CREATE_RESPONSE" | jq -r '.message // .error // "Unknown error"')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ACCESS_TOKEN=$(echo "$CREATE_RESPONSE" | jq -r '.data.accessToken')
|
||||
USER_SERIAL_NUM=$(echo "$CREATE_RESPONSE" | jq -r '.data.userSerialNum')
|
||||
USERNAME=$(echo "$CREATE_RESPONSE" | jq -r '.data.username')
|
||||
REFERRAL_CODE=$(echo "$CREATE_RESPONSE" | jq -r '.data.referralCode')
|
||||
|
||||
echo "✅ Account created successfully!"
|
||||
echo " User Serial Number: $USER_SERIAL_NUM"
|
||||
echo " Username: $USERNAME"
|
||||
echo " Referral Code: $REFERRAL_CODE"
|
||||
echo ""
|
||||
|
||||
# Step 2: Poll Wallet Status
|
||||
echo "[Step 2] Polling wallet status..."
|
||||
echo " Max retries: $MAX_RETRIES"
|
||||
echo " Retry interval: ${RETRY_INTERVAL}s"
|
||||
echo ""
|
||||
|
||||
RETRY_COUNT=0
|
||||
WALLET_READY=false
|
||||
|
||||
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
|
||||
RETRY_COUNT=$((RETRY_COUNT + 1))
|
||||
|
||||
WALLET_RESPONSE=$(curl -s -X GET "${BASE_URL}/user/wallet" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}")
|
||||
|
||||
WALLET_STATUS=$(echo "$WALLET_RESPONSE" | jq -r '.data.status // "unknown"')
|
||||
|
||||
echo "[Attempt $RETRY_COUNT/$MAX_RETRIES] Wallet status: $WALLET_STATUS"
|
||||
|
||||
if [ "$WALLET_STATUS" == "ready" ]; then
|
||||
WALLET_READY=true
|
||||
break
|
||||
elif [ "$WALLET_STATUS" == "failed" ]; then
|
||||
echo "❌ Wallet generation failed!"
|
||||
echo "Error: $(echo "$WALLET_RESPONSE" | jq -r '.data.error // "Unknown error"')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Still generating, wait and retry
|
||||
sleep $RETRY_INTERVAL
|
||||
done
|
||||
|
||||
if [ "$WALLET_READY" != "true" ]; then
|
||||
echo "❌ Timeout waiting for wallet to be ready!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=============================================="
|
||||
echo "✅ WALLET READY!"
|
||||
echo "=============================================="
|
||||
echo ""
|
||||
|
||||
# Extract wallet data
|
||||
MNEMONIC=$(echo "$WALLET_RESPONSE" | jq -r '.data.mnemonic // "N/A"')
|
||||
KAVA_ADDRESS=$(echo "$WALLET_RESPONSE" | jq -r '.data.walletAddresses.kava // "N/A"')
|
||||
DST_ADDRESS=$(echo "$WALLET_RESPONSE" | jq -r '.data.walletAddresses.dst // "N/A"')
|
||||
BSC_ADDRESS=$(echo "$WALLET_RESPONSE" | jq -r '.data.walletAddresses.bsc // "N/A"')
|
||||
|
||||
echo "📝 Mnemonic (12 words):"
|
||||
echo " $MNEMONIC"
|
||||
echo ""
|
||||
echo "💰 Wallet Addresses:"
|
||||
echo " KAVA: $KAVA_ADDRESS"
|
||||
echo " DST: $DST_ADDRESS"
|
||||
echo " BSC: $BSC_ADDRESS"
|
||||
echo ""
|
||||
echo "=============================================="
|
||||
echo "Test completed successfully!"
|
||||
echo "=============================================="
|
||||
|
||||
# Validate results
|
||||
if [ "$MNEMONIC" == "N/A" ] || [ -z "$MNEMONIC" ]; then
|
||||
echo "⚠️ Warning: Mnemonic is empty or N/A"
|
||||
fi
|
||||
|
||||
WORD_COUNT=$(echo "$MNEMONIC" | wc -w)
|
||||
if [ "$WORD_COUNT" -ne 12 ] && [ "$MNEMONIC" != "N/A" ] && [ -n "$MNEMONIC" ]; then
|
||||
echo "⚠️ Warning: Mnemonic word count is $WORD_COUNT (expected 12)"
|
||||
fi
|
||||
|
||||
if [ "$KAVA_ADDRESS" == "N/A" ] || [ "$DST_ADDRESS" == "N/A" ] || [ "$BSC_ADDRESS" == "N/A" ]; then
|
||||
echo "⚠️ Warning: Some wallet addresses are missing"
|
||||
fi
|
||||
|
|
@ -1,305 +0,0 @@
|
|||
{
|
||||
"name": "mnemonic-test",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/@adraffy/ens-normalize": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz",
|
||||
"integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@cosmjs/crypto": {
|
||||
"version": "0.37.0",
|
||||
"resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.37.0.tgz",
|
||||
"integrity": "sha512-rjnU7SEgNTUQAUotG686m7ahYSWgHh3J6n2JXoWoHJz0uVv4o4P+pbAFklyQ1PcPIR7u6LezCKDB5tP5Y5PeYQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@cosmjs/encoding": "^0.37.0",
|
||||
"@cosmjs/math": "^0.37.0",
|
||||
"@cosmjs/utils": "^0.37.0",
|
||||
"@noble/ciphers": "^1.3.0",
|
||||
"@noble/curves": "^1.9.2",
|
||||
"@noble/hashes": "^1.8.0",
|
||||
"@scure/bip39": "^1.6.0",
|
||||
"hash-wasm": "^4.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@cosmjs/encoding": {
|
||||
"version": "0.37.0",
|
||||
"resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.37.0.tgz",
|
||||
"integrity": "sha512-xtdC0w+iVFOrod9a5RLJULUECv+6AvZr5FkD8AFr2vD853n7Z89/AVuEiJzd4GdUwlPzxcaamhAtmI+IB9DYvg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@scure/base": "^2.0.0",
|
||||
"base64-js": "^1.3.0",
|
||||
"readonly-date": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@cosmjs/math": {
|
||||
"version": "0.37.0",
|
||||
"resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.37.0.tgz",
|
||||
"integrity": "sha512-FI+Tq8mhW0tuDawRvPdyX3K7qDZD2v1keRhiK/zHisvtQVzqoRRoOS1g5P9Pc7gWLQ1jPS15gDMYBu5+UYJ1+g==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@cosmjs/utils": {
|
||||
"version": "0.37.0",
|
||||
"resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.37.0.tgz",
|
||||
"integrity": "sha512-j46yZg+cLBpANGc5sCxtQHJgPGBt5zSKlU+KX9FlDS6JU6q2vZYCpKgucFFpjekEiMagU1eu8cDSCRjTthEM6w==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@noble/ciphers": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz",
|
||||
"integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/curves": {
|
||||
"version": "1.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz",
|
||||
"integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/hashes": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/base": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@scure/base/-/base-2.0.0.tgz",
|
||||
"integrity": "sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip32": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-2.0.1.tgz",
|
||||
"integrity": "sha512-4Md1NI5BzoVP+bhyJaY3K6yMesEFzNS1sE/cP+9nuvE7p/b0kx9XbpDHHFl8dHtufcbdHRUUQdRqLIPHN/s7yA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/curves": "2.0.1",
|
||||
"@noble/hashes": "2.0.1",
|
||||
"@scure/base": "2.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip32/node_modules/@noble/curves": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-2.0.1.tgz",
|
||||
"integrity": "sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip32/node_modules/@noble/hashes": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz",
|
||||
"integrity": "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip39": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz",
|
||||
"integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "~1.8.0",
|
||||
"@scure/base": "~1.2.5"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@scure/bip39/node_modules/@scure/base": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz",
|
||||
"integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz",
|
||||
"integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.2"
|
||||
}
|
||||
},
|
||||
"node_modules/aes-js": {
|
||||
"version": "4.0.0-beta.5",
|
||||
"resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz",
|
||||
"integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bip39": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz",
|
||||
"integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ethers": {
|
||||
"version": "6.16.0",
|
||||
"resolved": "https://registry.npmjs.org/ethers/-/ethers-6.16.0.tgz",
|
||||
"integrity": "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/ethers-io/"
|
||||
},
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://www.buymeacoffee.com/ricmoo"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@adraffy/ens-normalize": "1.10.1",
|
||||
"@noble/curves": "1.2.0",
|
||||
"@noble/hashes": "1.3.2",
|
||||
"@types/node": "22.7.5",
|
||||
"aes-js": "4.0.0-beta.5",
|
||||
"tslib": "2.7.0",
|
||||
"ws": "8.17.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ethers/node_modules/@noble/curves": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz",
|
||||
"integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.3.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/ethers/node_modules/@noble/hashes": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz",
|
||||
"integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/hash-wasm": {
|
||||
"version": "4.12.0",
|
||||
"resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.12.0.tgz",
|
||||
"integrity": "sha512-+/2B2rYLb48I/evdOIhP+K/DD2ca2fgBjp6O+GBEnCDk2e4rpeXIK8GvIyRPjTezgmWn9gmKwkQjjx6BtqDHVQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/readonly-date": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/readonly-date/-/readonly-date-1.0.0.tgz",
|
||||
"integrity": "sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
|
||||
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.19.8",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021 Andrew Raffensperger
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -1,206 +0,0 @@
|
|||
# ens-normalize.js
|
||||
0-dependancy [Ethereum Name Service](https://ens.domains/) (ENS) Name Normalizer.
|
||||
|
||||
* 🏛️ Follows [ENSIP-15: ENS Name Normalization Standard](https://docs.ens.domains/ens-improvement-proposals/ensip-15-normalization-standard)
|
||||
* Other implementations:
|
||||
* Python — [namehash/ens-normalize-python](https://github.com/namehash/ens-normalize-python)
|
||||
* C# — [adraffy/ENSNormalize.cs](https://github.com/adraffy/ENSNormalize.cs)
|
||||
* Java — [adraffy/ENSNormalize.java](https://github.com/adraffy/ENSNormalize.java)
|
||||
* Javascript — [ensdomains/eth-ens-namehash](https://github.com/ensdomains/eth-ens-namehash)
|
||||
* [Breakdown Reports from ENSIP-1](https://adraffy.github.io/ens-norm-tests/test-breakdown/output-20230226/)
|
||||
* ✅️ Passes **100%** [ENSIP-15 Validation Tests](https://adraffy.github.io/ens-normalize.js/test/validate.html)
|
||||
* ✅️ Passes **100%** [Unicode Normalization Tests](https://adraffy.github.io/ens-normalize.js/test/report-nf.html)
|
||||
* Minified File Sizes:
|
||||
* [`28KB`](./dist/index-xnf.min.js) — native `NFC` via [nf-native.js](./src/nf-native.js) using `String.normalize()` ⚠️
|
||||
* [`37KB` **Default**](./dist/index.min.js) — custom `NFC` via [nf.js](./src/nf.js)
|
||||
* [`43KB`](./dist/all.min.js) *Everything!* — custom `NFC` + sub-libraries: [parts.js](./src/parts.js), [utils.js](./src/utils.js)
|
||||
* Included Apps:
|
||||
* [**Resolver Demo**](https://adraffy.github.io/ens-normalize.js/test/resolver.html) ⭐
|
||||
* [Supported Emoji](https://adraffy.github.io/ens-normalize.js/test/emoji.html)
|
||||
* [Character Viewer](https://adraffy.github.io/ens-normalize.js/test/chars.html)
|
||||
* [Confused Explainer](https://adraffy.github.io/ens-normalize.js/test/confused.html)
|
||||
* Related Projects:
|
||||
* [Recent .eth Registrations](https://raffy.antistupid.com/eth/ens-regs.html) • [.eth Renews](https://raffy.antistupid.com/eth/ens-renews.html)
|
||||
* [.eth Expirations](https://raffy.antistupid.com/eth/ens-exp.html)
|
||||
* [Emoji Frequency Explorer](https://raffy.antistupid.com/eth/ens-emoji-freq.html)
|
||||
* [ENS+NFT Matcher](https://raffy.antistupid.com/eth/ens-nft-matcher.html)
|
||||
* [Batch Resolver](https://raffy.antistupid.com/eth/ens-batch-resolver.html)
|
||||
* [Label Database](https://github.com/adraffy/ens-labels/) • [Labelhash⁻¹](https://adraffy.github.io/ens-labels/demo.html)
|
||||
* [adraffy/punycode.js](https://github.com/adraffy/punycode.js/) • [Punycode Coder](https://adraffy.github.io/punycode.js/test/demo.html)
|
||||
* [adraffy/keccak.js](https://github.com/adraffy/keccak.js/) • [Keccak Hasher](https://adraffy.github.io/keccak.js/test/demo.html)
|
||||
* [adraffy/emoji.js](https://github.com/adraffy/emoji.js/) • [Emoji Parser](https://adraffy.github.io/emoji.js/test/demo.html)
|
||||
|
||||
```js
|
||||
import {ens_normalize} from '@adraffy/ens-normalize'; // or require()
|
||||
// npm i @adraffy/ens-normalize
|
||||
// browser: https://cdn.jsdelivr.net/npm/@adraffy/ens-normalize@latest/dist/index.min.mjs (or .cjs)
|
||||
|
||||
// *** ALL errors thrown by this library are safe to print ***
|
||||
// - characters are shown as {HEX} if should_escape()
|
||||
// - potentially different bidi directions inside "quotes"
|
||||
// - 200E is used near "quotes" to prevent spillover
|
||||
// - an "error type" can be extracted by slicing up to the first (:)
|
||||
// - labels are middle-truncated with ellipsis (…) at 63 cps
|
||||
|
||||
// string -> string
|
||||
// throws on invalid names
|
||||
// output ready for namehash
|
||||
let normalized = ens_normalize('RaFFY🚴♂️.eTh');
|
||||
// => "raffy🚴♂.eth"
|
||||
|
||||
// note: does not enforce .eth registrar 3-character minimum
|
||||
```
|
||||
|
||||
Format names with fully-qualified emoji:
|
||||
```js
|
||||
// works like ens_normalize()
|
||||
// output ready for display
|
||||
let pretty = ens_beautify('1⃣2⃣.eth');
|
||||
// => "1️⃣2️⃣.eth"
|
||||
|
||||
// note: normalization is unchanged:
|
||||
// ens_normalize(ens_beautify(x)) == ens_normalize(x)
|
||||
```
|
||||
|
||||
Normalize name fragments for [substring search](./test/fragment.js):
|
||||
```js
|
||||
// these fragments fail ens_normalize()
|
||||
// but will normalize fine as fragments
|
||||
let frag1 = ens_normalize_fragment('AB--'); // expected error: label ext
|
||||
let frag2 = ens_normalize_fragment('\u{303}'); // expected error: leading cm
|
||||
let frag3 = ens_normalize_fragment('οо'); // expected error: mixture
|
||||
```
|
||||
|
||||
Input-based tokenization:
|
||||
```js
|
||||
// string -> Token[]
|
||||
// never throws
|
||||
let tokens = ens_tokenize('_R💩\u{FE0F}a\u{FE0F}\u{304}\u{AD}./');
|
||||
// [
|
||||
// { type: 'valid', cp: [ 95 ] }, // valid (as-is)
|
||||
// {
|
||||
// type: 'mapped',
|
||||
// cp: 82, // input
|
||||
// cps: [ 114 ] // output
|
||||
// },
|
||||
// {
|
||||
// type: 'emoji',
|
||||
// input: Emoji(2) [ 128169, 65039 ], // input
|
||||
// emoji: [ 128169, 65039 ], // fully-qualified
|
||||
// cps: Emoji(1) [ 128169 ] // output (normalized)
|
||||
// },
|
||||
// {
|
||||
// type: 'nfc',
|
||||
// input: [ 97, 772 ], // input (before nfc)
|
||||
// tokens0: [ // tokens (before nfc)
|
||||
// { type: 'valid', cps: [ 97 ] },
|
||||
// { type: 'ignored', cp: 65039 },
|
||||
// { type: 'valid', cps: [ 772 ] }
|
||||
// ],
|
||||
// cps: [ 257 ], // output (after nfc)
|
||||
// tokens: [ // tokens (after nfc)
|
||||
// { type: 'valid', cps: [ 257 ] }
|
||||
// ]
|
||||
// },
|
||||
// { type: 'ignored', cp: 173 },
|
||||
// { type: 'stop', cp: 46 },
|
||||
// { type: 'disallowed', cp: 47 }
|
||||
// ]
|
||||
|
||||
// note: if name is normalizable, then:
|
||||
// ens_normalize(ens_tokenize(name).map(token => {
|
||||
// ** convert valid/mapped/nfc/stop to string **
|
||||
// }).join('')) == ens_normalize(name)
|
||||
```
|
||||
|
||||
Output-based tokenization:
|
||||
```js
|
||||
// string -> Label[]
|
||||
// never throws
|
||||
let labels = ens_split('💩Raffy.eth_');
|
||||
// [
|
||||
// {
|
||||
// input: [ 128169, 82, 97, 102, 102, 121 ],
|
||||
// offset: 0, // index of codepoint, not substring index!
|
||||
// // (corresponding length can be inferred from input)
|
||||
// tokens: [
|
||||
// Emoji(2) [ 128169, 65039 ], // emoji
|
||||
// [ 114, 97, 102, 102, 121 ] // nfc-text
|
||||
// ],
|
||||
// output: [ 128169, 114, 97, 102, 102, 121 ],
|
||||
// emoji: true,
|
||||
// type: 'Latin'
|
||||
// },
|
||||
// {
|
||||
// input: [ 101, 116, 104, 95 ],
|
||||
// offset: 7,
|
||||
// tokens: [ [ 101, 116, 104, 95 ] ],
|
||||
// output: [ 101, 116, 104, 95 ],
|
||||
// error: Error('underscore allowed only at start')
|
||||
// }
|
||||
// ]
|
||||
```
|
||||
|
||||
Generate a sorted array of (beautified) supported emoji codepoints:
|
||||
```js
|
||||
// () -> number[][]
|
||||
let emojis = ens_emoji();
|
||||
// [
|
||||
// [ 2764 ],
|
||||
// [ 128169, 65039 ],
|
||||
// [ 128105, 127997, 8205, 9877, 65039 ],
|
||||
// ...
|
||||
// ]
|
||||
```
|
||||
|
||||
Determine if a character shouldn't be printed directly:
|
||||
```js
|
||||
// number -> bool
|
||||
should_escape(0x202E); // eg. RIGHT-TO-LEFT OVERRIDE => true
|
||||
```
|
||||
|
||||
Determine if a character is a combining mark:
|
||||
```js
|
||||
// number -> bool
|
||||
is_combining_mark(0x20E3); // eg. COMBINING ENCLOSING KEYCAP => true
|
||||
```
|
||||
|
||||
Format codepoints as print-safe string:
|
||||
```js
|
||||
// number[] -> string
|
||||
safe_str_from_cps([0x300, 0, 32, 97]); // "◌̀{00} a"
|
||||
safe_str_from_cps(Array(100).fill(97), 4); // "aa…aa" => middle-truncated
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
* `git clone` this repo, then `npm install`
|
||||
* Follow instructions in [/derive/](./derive/) to generate data files
|
||||
* `npm run derive`
|
||||
* [spec.json](./derive/output/spec.json)
|
||||
* [nf.json](./derive/output/nf.json)
|
||||
* [nf-tests.json](./derive/output/nf-tests.json)
|
||||
* `npm run make` — compress data files from [/derive/output/](./derive/output/)
|
||||
* [include-ens.js](./src/include-ens.js)
|
||||
* [include-nf.js](./src/include-nf.js)
|
||||
* [include-versions.js](./src/include-versions.js)
|
||||
* Follow instructions in [/validate/](./validate/) to generate validation tests
|
||||
* `npm run validate`
|
||||
* [tests.json](./validate/tests.json)
|
||||
* `npm run test` — perform validation tests
|
||||
* `npm run build` — create [/dist/](./dist/)
|
||||
* `npm run rebuild` — run all the commands above
|
||||
* `npm run order` — create optimal group ordering and rebuild again
|
||||
|
||||
### Publishing to NPM
|
||||
|
||||
This project uses `.js` instead of `.mjs` so [package.json](./package.json) uses `type: module`. To avoid bundling issues, `type` is [dropped during packing](./src/prepost.js). `pre/post` hooks aren't used because they're buggy.
|
||||
* `npm run pack` instead of `npm pack`
|
||||
* `npm run pub` instead of `npm publish`
|
||||
|
||||
## Security
|
||||
|
||||
* [Build](#build) and compare against [include-versions.js](./src/include-versions.js)
|
||||
* `spec_hash` — SHA-256 of [spec.json](./derive/output/spec.json) bytes
|
||||
* `base64_ens_hash` — SHA-256 of [include-ens.js](./src/include-ens.js) base64 literal
|
||||
* `base64_nf_hash` — SHA-256 of [include-nf.js](./src/include-nf.js) base64 literal
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,59 +0,0 @@
|
|||
interface DisallowedToken {
|
||||
type: 'disallowed';
|
||||
cp: number;
|
||||
}
|
||||
interface IgnoredToken {
|
||||
type: 'ignored';
|
||||
cp: number;
|
||||
}
|
||||
interface ValidToken {
|
||||
type: 'valid';
|
||||
cps: number[];
|
||||
}
|
||||
interface MappedToken {
|
||||
type: 'mapped';
|
||||
cp: number;
|
||||
cps: number[];
|
||||
}
|
||||
type TextToken = DisallowedToken | IgnoredToken | ValidToken | MappedToken;
|
||||
interface EmojiToken {
|
||||
type: 'emoji';
|
||||
input: number[];
|
||||
emoji: number[];
|
||||
cps: number[];
|
||||
}
|
||||
interface NFCToken {
|
||||
type: 'nfc';
|
||||
input: number[];
|
||||
cps: number[];
|
||||
tokens: TextToken[];
|
||||
}
|
||||
interface StopToken {
|
||||
type: 'stop';
|
||||
}
|
||||
type Token = TextToken | EmojiToken | NFCToken | StopToken;
|
||||
|
||||
interface Label {
|
||||
input: number[];
|
||||
offset: number;
|
||||
error?: Error;
|
||||
tokens?: number[][];
|
||||
output?: number[];
|
||||
emoji?: boolean;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
export function ens_normalize(name: string): string;
|
||||
export function ens_normalize_fragment(frag: string, decompose?: boolean): string;
|
||||
export function ens_beautify(name: string): string;
|
||||
export function ens_tokenize(name: string, options?: {nf?: boolean}): Token[];
|
||||
export function ens_split(name: string, preserve_emoji?: boolean): Label[];
|
||||
|
||||
export function ens_emoji(): number[][];
|
||||
|
||||
export function should_escape(cp: number): boolean;
|
||||
export function is_combining_mark(cp: number): boolean;
|
||||
export function safe_str_from_cps(cps: number[]): string;
|
||||
|
||||
export function nfd(cps: number[]): number[];
|
||||
export function nfc(cps: number[]): number[];
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,76 +0,0 @@
|
|||
{
|
||||
"name": "@adraffy/ens-normalize",
|
||||
"version": "1.10.1",
|
||||
"description": "Ethereum Name Service (ENS) Name Normalizer",
|
||||
"keywords": [
|
||||
"ENS",
|
||||
"ENSIP-1",
|
||||
"ENSIP-15",
|
||||
"Ethereum",
|
||||
"UTS-46",
|
||||
"UTS-51",
|
||||
"IDNA",
|
||||
"Name",
|
||||
"Normalize",
|
||||
"Normalization",
|
||||
"NFC",
|
||||
"NFD"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.mjs",
|
||||
"default": "./dist/index.cjs"
|
||||
},
|
||||
"./xnf": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index-xnf.mjs",
|
||||
"default": "./dist/index-xnf.cjs"
|
||||
}
|
||||
},
|
||||
"types": "./dist/index.d.ts",
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"*": [
|
||||
"./dist/index.d.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"files": [
|
||||
"./dist"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/adraffy/ens-normalize.js.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/adraffy/ens-normalize.js/issues"
|
||||
},
|
||||
"homepage": "https://github.com/adraffy/ens-normalize.js#readme",
|
||||
"author": {
|
||||
"name": "raffy.eth",
|
||||
"email": "raffy@me.com",
|
||||
"url": "http://raffy.antistupid.com"
|
||||
},
|
||||
"scripts": {
|
||||
"unicode": "node derive/download.js",
|
||||
"labels": "node validate/download-labels.js",
|
||||
"derive": "node derive/make.js",
|
||||
"make": "node src/make.js",
|
||||
"validate": "node validate/make.js",
|
||||
"test": "node test/coder.js && node test/nf.js && node test/validate.js && node test/init.js",
|
||||
"build": "rollup -c",
|
||||
"rebuild": "npm run derive && npm run make && npm run validate && npm run test && npm run build",
|
||||
"order": "node validate/dump-group-order.js save && npm run rebuild",
|
||||
"pack": "node ./src/prepost.js pack",
|
||||
"pub": "node ./src/prepost.js publish"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-alias": "^5.0.0",
|
||||
"@rollup/plugin-terser": "^0.4.0",
|
||||
"rollup": "^3.24.1"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
# @cosmjs/crypto
|
||||
|
||||

|
||||
[](https://www.npmjs.com/package/@cosmjs/crypto)
|
||||
[](https://github.com/cosmos/cosmjs/blob/v0.35.0/LICENSE)
|
||||

|
||||

|
||||

|
||||
|
||||
This package contains low-level cryptographic functionality used in other
|
||||
@cosmjs libraries. Little of it is implemented here, but mainly it is a curation
|
||||
of external libraries along with correctness tests. We add type safety, some
|
||||
more checks, and a simple API to these libraries. This can also be freely
|
||||
imported outside of CosmJS based applications.
|
||||
|
||||
## License
|
||||
|
||||
This package is part of the cosmjs repository, licensed under the Apache License
|
||||
2.0 (see [NOTICE](https://github.com/cosmos/cosmjs/blob/main/NOTICE) and
|
||||
[LICENSE](https://github.com/cosmos/cosmjs/blob/main/LICENSE)).
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
export declare class EnglishMnemonic {
|
||||
static readonly wordlist: readonly string[];
|
||||
private readonly data;
|
||||
constructor(mnemonic: string);
|
||||
toString(): string;
|
||||
}
|
||||
export declare class Bip39 {
|
||||
/**
|
||||
* Encodes raw entropy of length 16, 20, 24, 28 or 32 bytes as an English mnemonic between 12 and 24 words.
|
||||
*
|
||||
* | Entropy | Words |
|
||||
* |--------------------|-------|
|
||||
* | 128 bit (16 bytes) | 12 |
|
||||
* | 160 bit (20 bytes) | 15 |
|
||||
* | 192 bit (24 bytes) | 18 |
|
||||
* | 224 bit (28 bytes) | 21 |
|
||||
* | 256 bit (32 bytes) | 24 |
|
||||
*
|
||||
*
|
||||
* @see https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki#generating-the-mnemonic
|
||||
* @param entropy The entropy to be encoded. This must be cryptographically secure.
|
||||
*/
|
||||
static encode(entropy: Uint8Array): EnglishMnemonic;
|
||||
static decode(mnemonic: EnglishMnemonic): Uint8Array;
|
||||
static mnemonicToSeed(mnemonic: EnglishMnemonic, password?: string): Promise<Uint8Array>;
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Bip39 = exports.EnglishMnemonic = void 0;
|
||||
const bip39_1 = require("@scure/bip39");
|
||||
const english_1 = require("@scure/bip39/wordlists/english");
|
||||
class EnglishMnemonic {
|
||||
static wordlist = english_1.wordlist;
|
||||
data;
|
||||
constructor(mnemonic) {
|
||||
// throws an error if mnemonic is invalid
|
||||
const _ = (0, bip39_1.mnemonicToEntropy)(mnemonic, english_1.wordlist);
|
||||
this.data = mnemonic;
|
||||
}
|
||||
toString() {
|
||||
return this.data;
|
||||
}
|
||||
}
|
||||
exports.EnglishMnemonic = EnglishMnemonic;
|
||||
class Bip39 {
|
||||
/**
|
||||
* Encodes raw entropy of length 16, 20, 24, 28 or 32 bytes as an English mnemonic between 12 and 24 words.
|
||||
*
|
||||
* | Entropy | Words |
|
||||
* |--------------------|-------|
|
||||
* | 128 bit (16 bytes) | 12 |
|
||||
* | 160 bit (20 bytes) | 15 |
|
||||
* | 192 bit (24 bytes) | 18 |
|
||||
* | 224 bit (28 bytes) | 21 |
|
||||
* | 256 bit (32 bytes) | 24 |
|
||||
*
|
||||
*
|
||||
* @see https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki#generating-the-mnemonic
|
||||
* @param entropy The entropy to be encoded. This must be cryptographically secure.
|
||||
*/
|
||||
static encode(entropy) {
|
||||
return new EnglishMnemonic((0, bip39_1.entropyToMnemonic)(entropy, english_1.wordlist));
|
||||
}
|
||||
static decode(mnemonic) {
|
||||
return (0, bip39_1.mnemonicToEntropy)(mnemonic.toString(), english_1.wordlist);
|
||||
}
|
||||
static async mnemonicToSeed(mnemonic, password) {
|
||||
return await (0, bip39_1.mnemonicToSeed)(mnemonic.toString(), password);
|
||||
}
|
||||
}
|
||||
exports.Bip39 = Bip39;
|
||||
//# sourceMappingURL=bip39.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"bip39.js","sourceRoot":"","sources":["../src/bip39.ts"],"names":[],"mappings":";;;AAAA,wCAAoF;AACpF,4DAA0D;AAE1D,MAAa,eAAe;IACnB,MAAM,CAAU,QAAQ,GAAsB,kBAAQ,CAAC;IAE7C,IAAI,CAAS;IAE9B,YAAmB,QAAgB;QACjC,yCAAyC;QACzC,MAAM,CAAC,GAAG,IAAA,yBAAiB,EAAC,QAAQ,EAAE,kBAAQ,CAAC,CAAC;QAEhD,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,CAAC;IAEM,QAAQ;QACb,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;;AAdH,0CAeC;AAED,MAAa,KAAK;IAChB;;;;;;;;;;;;;;OAcG;IACI,MAAM,CAAC,MAAM,CAAC,OAAmB;QACtC,OAAO,IAAI,eAAe,CAAC,IAAA,yBAAiB,EAAC,OAAO,EAAE,kBAAQ,CAAC,CAAC,CAAC;IACnE,CAAC;IAEM,MAAM,CAAC,MAAM,CAAC,QAAyB;QAC5C,OAAO,IAAA,yBAAiB,EAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,kBAAQ,CAAC,CAAC;IAC1D,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,QAAyB,EAAE,QAAiB;QAC7E,OAAO,MAAM,IAAA,sBAAc,EAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC7D,CAAC;CACF;AA3BD,sBA2BC"}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
export interface HashFunction {
|
||||
readonly blockSize: number;
|
||||
readonly update: (_: Uint8Array) => HashFunction;
|
||||
readonly digest: () => Uint8Array;
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=hash.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":""}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import { HashFunction } from "./hash";
|
||||
export declare class Hmac<H extends HashFunction> implements HashFunction {
|
||||
readonly blockSize: number;
|
||||
private readonly messageHasher;
|
||||
private readonly oKeyPad;
|
||||
private readonly iKeyPad;
|
||||
private readonly hash;
|
||||
constructor(hashFunctionConstructor: new () => H, originalKey: Uint8Array);
|
||||
update(data: Uint8Array): this;
|
||||
digest(): Uint8Array;
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Hmac = void 0;
|
||||
class Hmac {
|
||||
blockSize;
|
||||
messageHasher;
|
||||
oKeyPad;
|
||||
iKeyPad;
|
||||
hash;
|
||||
constructor(hashFunctionConstructor, originalKey) {
|
||||
// This implementation is based on https://en.wikipedia.org/wiki/HMAC#Implementation
|
||||
// with the addition of incremental hashing support. Thus part of the algorithm
|
||||
// is in the constructor and the rest in digest().
|
||||
const blockSize = new hashFunctionConstructor().blockSize;
|
||||
this.hash = (data) => new hashFunctionConstructor().update(data).digest();
|
||||
let key = originalKey;
|
||||
if (key.length > blockSize) {
|
||||
key = this.hash(key);
|
||||
}
|
||||
if (key.length < blockSize) {
|
||||
const zeroPadding = new Uint8Array(blockSize - key.length);
|
||||
key = new Uint8Array([...key, ...zeroPadding]);
|
||||
}
|
||||
// eslint-disable-next-line no-bitwise
|
||||
this.oKeyPad = key.map((keyByte) => keyByte ^ 0x5c);
|
||||
// eslint-disable-next-line no-bitwise
|
||||
this.iKeyPad = key.map((keyByte) => keyByte ^ 0x36);
|
||||
this.messageHasher = new hashFunctionConstructor();
|
||||
this.blockSize = blockSize;
|
||||
this.update(this.iKeyPad);
|
||||
}
|
||||
update(data) {
|
||||
this.messageHasher.update(data);
|
||||
return this;
|
||||
}
|
||||
digest() {
|
||||
const innerHash = this.messageHasher.digest();
|
||||
return this.hash(new Uint8Array([...this.oKeyPad, ...innerHash]));
|
||||
}
|
||||
}
|
||||
exports.Hmac = Hmac;
|
||||
//# sourceMappingURL=hmac.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"hmac.js","sourceRoot":"","sources":["../src/hmac.ts"],"names":[],"mappings":";;;AAEA,MAAa,IAAI;IACC,SAAS,CAAS;IAEjB,aAAa,CAAI;IACjB,OAAO,CAAa;IACpB,OAAO,CAAa;IACpB,IAAI,CAAmC;IAExD,YAAmB,uBAAoC,EAAE,WAAuB;QAC9E,oFAAoF;QACpF,+EAA+E;QAC/E,kDAAkD;QAElD,MAAM,SAAS,GAAG,IAAI,uBAAuB,EAAE,CAAC,SAAS,CAAC;QAE1D,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,uBAAuB,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;QAE1E,IAAI,GAAG,GAAG,WAAW,CAAC;QACtB,IAAI,GAAG,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;YAC3D,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC;QACjD,CAAC;QAED,sCAAsC;QACtC,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;QACpD,sCAAsC;QACtC,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,aAAa,GAAG,IAAI,uBAAuB,EAAE,CAAC;QACnD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAE3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAEM,MAAM,CAAC,IAAgB;QAC5B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,MAAM;QACX,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC;CACF;AA9CD,oBA8CC"}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
export { Bip39, EnglishMnemonic } from "./bip39";
|
||||
export type { HashFunction } from "./hash";
|
||||
export { Hmac } from "./hmac";
|
||||
export { Keccak256, keccak256 } from "./keccak";
|
||||
export { type Argon2idOptions, Argon2id, Ed25519, Ed25519Keypair, isArgon2idOptions, xchacha20NonceLength, Xchacha20poly1305Ietf, } from "./libsodium";
|
||||
export { Random } from "./random";
|
||||
export { Ripemd160, ripemd160 } from "./ripemd";
|
||||
export { type Secp256k1Keypair, Secp256k1 } from "./secp256k1";
|
||||
export { ExtendedSecp256k1Signature, Secp256k1Signature } from "./secp256k1signature";
|
||||
export { Sha256, sha256, Sha512, sha512 } from "./sha";
|
||||
export type { HdPath, Slip10Result } from "./slip10";
|
||||
export { pathToString, Slip10, Slip10Curve, slip10CurveFromString, Slip10RawIndex, stringToPath, } from "./slip10";
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.stringToPath = exports.Slip10RawIndex = exports.slip10CurveFromString = exports.Slip10Curve = exports.Slip10 = exports.pathToString = exports.sha512 = exports.Sha512 = exports.sha256 = exports.Sha256 = exports.Secp256k1Signature = exports.ExtendedSecp256k1Signature = exports.Secp256k1 = exports.ripemd160 = exports.Ripemd160 = exports.Random = exports.Xchacha20poly1305Ietf = exports.xchacha20NonceLength = exports.isArgon2idOptions = exports.Ed25519Keypair = exports.Ed25519 = exports.Argon2id = exports.keccak256 = exports.Keccak256 = exports.Hmac = exports.EnglishMnemonic = exports.Bip39 = void 0;
|
||||
var bip39_1 = require("./bip39");
|
||||
Object.defineProperty(exports, "Bip39", { enumerable: true, get: function () { return bip39_1.Bip39; } });
|
||||
Object.defineProperty(exports, "EnglishMnemonic", { enumerable: true, get: function () { return bip39_1.EnglishMnemonic; } });
|
||||
var hmac_1 = require("./hmac");
|
||||
Object.defineProperty(exports, "Hmac", { enumerable: true, get: function () { return hmac_1.Hmac; } });
|
||||
var keccak_1 = require("./keccak");
|
||||
Object.defineProperty(exports, "Keccak256", { enumerable: true, get: function () { return keccak_1.Keccak256; } });
|
||||
Object.defineProperty(exports, "keccak256", { enumerable: true, get: function () { return keccak_1.keccak256; } });
|
||||
var libsodium_1 = require("./libsodium");
|
||||
Object.defineProperty(exports, "Argon2id", { enumerable: true, get: function () { return libsodium_1.Argon2id; } });
|
||||
Object.defineProperty(exports, "Ed25519", { enumerable: true, get: function () { return libsodium_1.Ed25519; } });
|
||||
Object.defineProperty(exports, "Ed25519Keypair", { enumerable: true, get: function () { return libsodium_1.Ed25519Keypair; } });
|
||||
Object.defineProperty(exports, "isArgon2idOptions", { enumerable: true, get: function () { return libsodium_1.isArgon2idOptions; } });
|
||||
Object.defineProperty(exports, "xchacha20NonceLength", { enumerable: true, get: function () { return libsodium_1.xchacha20NonceLength; } });
|
||||
Object.defineProperty(exports, "Xchacha20poly1305Ietf", { enumerable: true, get: function () { return libsodium_1.Xchacha20poly1305Ietf; } });
|
||||
var random_1 = require("./random");
|
||||
Object.defineProperty(exports, "Random", { enumerable: true, get: function () { return random_1.Random; } });
|
||||
var ripemd_1 = require("./ripemd");
|
||||
Object.defineProperty(exports, "Ripemd160", { enumerable: true, get: function () { return ripemd_1.Ripemd160; } });
|
||||
Object.defineProperty(exports, "ripemd160", { enumerable: true, get: function () { return ripemd_1.ripemd160; } });
|
||||
var secp256k1_1 = require("./secp256k1");
|
||||
Object.defineProperty(exports, "Secp256k1", { enumerable: true, get: function () { return secp256k1_1.Secp256k1; } });
|
||||
var secp256k1signature_1 = require("./secp256k1signature");
|
||||
Object.defineProperty(exports, "ExtendedSecp256k1Signature", { enumerable: true, get: function () { return secp256k1signature_1.ExtendedSecp256k1Signature; } });
|
||||
Object.defineProperty(exports, "Secp256k1Signature", { enumerable: true, get: function () { return secp256k1signature_1.Secp256k1Signature; } });
|
||||
var sha_1 = require("./sha");
|
||||
Object.defineProperty(exports, "Sha256", { enumerable: true, get: function () { return sha_1.Sha256; } });
|
||||
Object.defineProperty(exports, "sha256", { enumerable: true, get: function () { return sha_1.sha256; } });
|
||||
Object.defineProperty(exports, "Sha512", { enumerable: true, get: function () { return sha_1.Sha512; } });
|
||||
Object.defineProperty(exports, "sha512", { enumerable: true, get: function () { return sha_1.sha512; } });
|
||||
var slip10_1 = require("./slip10");
|
||||
Object.defineProperty(exports, "pathToString", { enumerable: true, get: function () { return slip10_1.pathToString; } });
|
||||
Object.defineProperty(exports, "Slip10", { enumerable: true, get: function () { return slip10_1.Slip10; } });
|
||||
Object.defineProperty(exports, "Slip10Curve", { enumerable: true, get: function () { return slip10_1.Slip10Curve; } });
|
||||
Object.defineProperty(exports, "slip10CurveFromString", { enumerable: true, get: function () { return slip10_1.slip10CurveFromString; } });
|
||||
Object.defineProperty(exports, "Slip10RawIndex", { enumerable: true, get: function () { return slip10_1.Slip10RawIndex; } });
|
||||
Object.defineProperty(exports, "stringToPath", { enumerable: true, get: function () { return slip10_1.stringToPath; } });
|
||||
//# sourceMappingURL=index.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iCAAiD;AAAxC,8FAAA,KAAK,OAAA;AAAE,wGAAA,eAAe,OAAA;AAE/B,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,mCAAgD;AAAvC,mGAAA,SAAS,OAAA;AAAE,mGAAA,SAAS,OAAA;AAC7B,yCAQqB;AANnB,qGAAA,QAAQ,OAAA;AACR,oGAAA,OAAO,OAAA;AACP,2GAAA,cAAc,OAAA;AACd,8GAAA,iBAAiB,OAAA;AACjB,iHAAA,oBAAoB,OAAA;AACpB,kHAAA,qBAAqB,OAAA;AAEvB,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,mCAAgD;AAAvC,mGAAA,SAAS,OAAA;AAAE,mGAAA,SAAS,OAAA;AAC7B,yCAA+D;AAA/B,sGAAA,SAAS,OAAA;AACzC,2DAAsF;AAA7E,gIAAA,0BAA0B,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AACvD,6BAAuD;AAA9C,6FAAA,MAAM,OAAA;AAAE,6FAAA,MAAM,OAAA;AAAE,6FAAA,MAAM,OAAA;AAAE,6FAAA,MAAM,OAAA;AAEvC,mCAOkB;AANhB,sGAAA,YAAY,OAAA;AACZ,gGAAA,MAAM,OAAA;AACN,qGAAA,WAAW,OAAA;AACX,+GAAA,qBAAqB,OAAA;AACrB,wGAAA,cAAc,OAAA;AACd,sGAAA,YAAY,OAAA"}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
import { HashFunction } from "./hash";
|
||||
export declare class Keccak256 implements HashFunction {
|
||||
readonly blockSize: number;
|
||||
private readonly impl;
|
||||
constructor(firstData?: Uint8Array);
|
||||
update(data: Uint8Array): this;
|
||||
digest(): Uint8Array;
|
||||
}
|
||||
/** Convenience function equivalent to `new Keccak256(data).digest()` */
|
||||
export declare function keccak256(data: Uint8Array): Uint8Array;
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Keccak256 = void 0;
|
||||
exports.keccak256 = keccak256;
|
||||
const sha3_js_1 = require("@noble/hashes/sha3.js");
|
||||
const utils_1 = require("./utils");
|
||||
class Keccak256 {
|
||||
blockSize = 512 / 8;
|
||||
impl = sha3_js_1.keccak_256.create();
|
||||
constructor(firstData) {
|
||||
if (firstData) {
|
||||
this.update(firstData);
|
||||
}
|
||||
}
|
||||
update(data) {
|
||||
this.impl.update((0, utils_1.toRealUint8Array)(data));
|
||||
return this;
|
||||
}
|
||||
digest() {
|
||||
return this.impl.digest();
|
||||
}
|
||||
}
|
||||
exports.Keccak256 = Keccak256;
|
||||
/** Convenience function equivalent to `new Keccak256(data).digest()` */
|
||||
function keccak256(data) {
|
||||
return new Keccak256(data).digest();
|
||||
}
|
||||
//# sourceMappingURL=keccak.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"keccak.js","sourceRoot":"","sources":["../src/keccak.ts"],"names":[],"mappings":";;;AA2BA,8BAEC;AA7BD,mDAAmD;AAGnD,mCAA2C;AAE3C,MAAa,SAAS;IACJ,SAAS,GAAG,GAAG,GAAG,CAAC,CAAC;IAEnB,IAAI,GAAG,oBAAU,CAAC,MAAM,EAAE,CAAC;IAE5C,YAAmB,SAAsB;QACvC,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,IAAgB;QAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAA,wBAAgB,EAAC,IAAI,CAAC,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;CACF;AAnBD,8BAmBC;AAED,wEAAwE;AACxE,SAAgB,SAAS,CAAC,IAAgB;IACxC,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;AACtC,CAAC"}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
export interface Argon2idOptions {
|
||||
/** Output length in bytes */
|
||||
readonly outputLength: number;
|
||||
/**
|
||||
* An integer between 1 and 4294967295 representing the computational difficulty.
|
||||
*
|
||||
* @see https://libsodium.gitbook.io/doc/password_hashing/default_phf#key-derivation
|
||||
*/
|
||||
readonly opsLimit: number;
|
||||
/**
|
||||
* Memory limit measured in KiB (like argon2 command line tool)
|
||||
*
|
||||
* Note: only approximately 16 MiB of memory are available using the non-sumo version of libsodium.js
|
||||
*
|
||||
* @see https://libsodium.gitbook.io/doc/password_hashing/default_phf#key-derivation
|
||||
*/
|
||||
readonly memLimitKib: number;
|
||||
}
|
||||
export declare function isArgon2idOptions(thing: unknown): thing is Argon2idOptions;
|
||||
export declare class Argon2id {
|
||||
static execute(password: string, salt: Uint8Array, options: Argon2idOptions): Promise<Uint8Array>;
|
||||
}
|
||||
export declare class Ed25519Keypair {
|
||||
static fromLibsodiumPrivkey(libsodiumPrivkey: Uint8Array): Ed25519Keypair;
|
||||
readonly privkey: Uint8Array;
|
||||
readonly pubkey: Uint8Array;
|
||||
constructor(privkey: Uint8Array, pubkey: Uint8Array);
|
||||
toLibsodiumPrivkey(): Uint8Array;
|
||||
}
|
||||
export declare class Ed25519 {
|
||||
/**
|
||||
* Generates a keypair deterministically from a given 32 bytes seed.
|
||||
*
|
||||
* This seed equals the Ed25519 private key.
|
||||
* For implementation details see crypto_sign_seed_keypair in
|
||||
* https://download.libsodium.org/doc/public-key_cryptography/public-key_signatures.html
|
||||
* and diagram on https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/
|
||||
*/
|
||||
static makeKeypair(privKey: Uint8Array): Promise<Ed25519Keypair>;
|
||||
static createSignature(message: Uint8Array, keyPair: Ed25519Keypair): Promise<Uint8Array>;
|
||||
static verifySignature(signature: Uint8Array, message: Uint8Array, pubkey: Uint8Array): Promise<boolean>;
|
||||
}
|
||||
/**
|
||||
* Nonce length in bytes for all flavours of XChaCha20.
|
||||
*
|
||||
* @see https://libsodium.gitbook.io/doc/advanced/stream_ciphers/xchacha20#notes
|
||||
*/
|
||||
export declare const xchacha20NonceLength = 24;
|
||||
export declare class Xchacha20poly1305Ietf {
|
||||
static encrypt(message: Uint8Array, key: Uint8Array, nonce: Uint8Array): Promise<Uint8Array>;
|
||||
static decrypt(ciphertext: Uint8Array, key: Uint8Array, nonce: Uint8Array): Promise<Uint8Array>;
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Xchacha20poly1305Ietf = exports.xchacha20NonceLength = exports.Ed25519 = exports.Ed25519Keypair = exports.Argon2id = void 0;
|
||||
exports.isArgon2idOptions = isArgon2idOptions;
|
||||
const utils_1 = require("@cosmjs/utils");
|
||||
const chacha_js_1 = require("@noble/ciphers/chacha.js");
|
||||
const ed25519_js_1 = require("@noble/curves/ed25519.js");
|
||||
const hash_wasm_1 = require("hash-wasm");
|
||||
function isArgon2idOptions(thing) {
|
||||
if (!(0, utils_1.isNonNullObject)(thing))
|
||||
return false;
|
||||
if (typeof thing.outputLength !== "number")
|
||||
return false;
|
||||
if (typeof thing.opsLimit !== "number")
|
||||
return false;
|
||||
if (typeof thing.memLimitKib !== "number")
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
class Argon2id {
|
||||
static async execute(password, salt, options) {
|
||||
const opts = {
|
||||
password,
|
||||
salt,
|
||||
outputType: "binary",
|
||||
iterations: options.opsLimit,
|
||||
memorySize: options.memLimitKib,
|
||||
parallelism: 1, // no parallelism allowed, just like libsodium
|
||||
hashLength: options.outputLength,
|
||||
};
|
||||
if (salt.length !== 16) {
|
||||
throw new Error(`Got invalid salt length ${salt.length}. Must be 16.`);
|
||||
}
|
||||
const hash = await (0, hash_wasm_1.argon2id)(opts);
|
||||
// guaranteed by outputType: 'binary'
|
||||
(0, utils_1.assert)(typeof hash !== "string");
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
exports.Argon2id = Argon2id;
|
||||
class Ed25519Keypair {
|
||||
// a libsodium privkey has the format `<ed25519 privkey> + <ed25519 pubkey>`
|
||||
static fromLibsodiumPrivkey(libsodiumPrivkey) {
|
||||
if (libsodiumPrivkey.length !== 64) {
|
||||
throw new Error(`Unexpected key length ${libsodiumPrivkey.length}. Must be 64.`);
|
||||
}
|
||||
return new Ed25519Keypair(libsodiumPrivkey.slice(0, 32), libsodiumPrivkey.slice(32, 64));
|
||||
}
|
||||
privkey;
|
||||
pubkey;
|
||||
constructor(privkey, pubkey) {
|
||||
this.privkey = privkey;
|
||||
this.pubkey = pubkey;
|
||||
}
|
||||
toLibsodiumPrivkey() {
|
||||
return new Uint8Array([...this.privkey, ...this.pubkey]);
|
||||
}
|
||||
}
|
||||
exports.Ed25519Keypair = Ed25519Keypair;
|
||||
class Ed25519 {
|
||||
/**
|
||||
* Generates a keypair deterministically from a given 32 bytes seed.
|
||||
*
|
||||
* This seed equals the Ed25519 private key.
|
||||
* For implementation details see crypto_sign_seed_keypair in
|
||||
* https://download.libsodium.org/doc/public-key_cryptography/public-key_signatures.html
|
||||
* and diagram on https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/
|
||||
*/
|
||||
static async makeKeypair(privKey) {
|
||||
const pubKey = ed25519_js_1.ed25519.getPublicKey(privKey);
|
||||
return new Ed25519Keypair(privKey, pubKey);
|
||||
}
|
||||
static async createSignature(message, keyPair) {
|
||||
return ed25519_js_1.ed25519.sign(message, keyPair.privkey);
|
||||
}
|
||||
static async verifySignature(signature, message, pubkey) {
|
||||
return ed25519_js_1.ed25519.verify(signature, message, pubkey);
|
||||
}
|
||||
}
|
||||
exports.Ed25519 = Ed25519;
|
||||
/**
|
||||
* Nonce length in bytes for all flavours of XChaCha20.
|
||||
*
|
||||
* @see https://libsodium.gitbook.io/doc/advanced/stream_ciphers/xchacha20#notes
|
||||
*/
|
||||
exports.xchacha20NonceLength = 24;
|
||||
class Xchacha20poly1305Ietf {
|
||||
static async encrypt(message, key, nonce) {
|
||||
const additionalAuthenticatedData = undefined;
|
||||
const cipher = (0, chacha_js_1.xchacha20poly1305)(key, nonce, additionalAuthenticatedData);
|
||||
return cipher.encrypt(message);
|
||||
}
|
||||
static async decrypt(ciphertext, key, nonce) {
|
||||
const additionalAuthenticatedData = undefined;
|
||||
const cipher = (0, chacha_js_1.xchacha20poly1305)(key, nonce, additionalAuthenticatedData);
|
||||
return cipher.decrypt(ciphertext);
|
||||
}
|
||||
}
|
||||
exports.Xchacha20poly1305Ietf = Xchacha20poly1305Ietf;
|
||||
//# sourceMappingURL=libsodium.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"libsodium.js","sourceRoot":"","sources":["../src/libsodium.ts"],"names":[],"mappings":"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"}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
/**
|
||||
* Returns the SubtleCrypto API for this environment if present.
|
||||
*
|
||||
* Right now (CosmJS 0.35), all supported environments we are aware of have
|
||||
* SubtleCrypto. However, we keep the optional return type just in case as we can
|
||||
* use the pure-JS fallback.
|
||||
*/
|
||||
export declare function getSubtle(): Promise<typeof crypto.subtle | undefined>;
|
||||
export declare function pbkdf2Sha512Subtle(subtle: typeof crypto.subtle, secret: Uint8Array, salt: Uint8Array, iterations: number, keylen: number): Promise<Uint8Array>;
|
||||
export declare function pbkdf2Sha512Noble(secret: Uint8Array, salt: Uint8Array, iterations: number, keylen: number): Promise<Uint8Array>;
|
||||
/**
|
||||
* A pbkdf2 implementation for BIP39. This is not exported at package level and thus a private API.
|
||||
*/
|
||||
export declare function pbkdf2Sha512(secret: Uint8Array, salt: Uint8Array, iterations: number, keylen: number): Promise<Uint8Array>;
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getSubtle = getSubtle;
|
||||
exports.pbkdf2Sha512Subtle = pbkdf2Sha512Subtle;
|
||||
exports.pbkdf2Sha512Noble = pbkdf2Sha512Noble;
|
||||
exports.pbkdf2Sha512 = pbkdf2Sha512;
|
||||
const utils_1 = require("@cosmjs/utils");
|
||||
const pbkdf2_js_1 = require("@noble/hashes/pbkdf2.js");
|
||||
const sha2_js_1 = require("@noble/hashes/sha2.js");
|
||||
/**
|
||||
* Returns the SubtleCrypto API for this environment if present.
|
||||
*
|
||||
* Right now (CosmJS 0.35), all supported environments we are aware of have
|
||||
* SubtleCrypto. However, we keep the optional return type just in case as we can
|
||||
* use the pure-JS fallback.
|
||||
*/
|
||||
async function getSubtle() {
|
||||
// From Node.js 15 onwards, webcrypto is available in globalThis.
|
||||
// In version 15 and 16 this was stored under the webcrypto key.
|
||||
// With Node.js 17 it was moved to the same locations where browsers
|
||||
// make it available.
|
||||
// Loading `require("crypto")` here seems unnecessary since it only
|
||||
// causes issues with bundlers and does not increase compatibility.
|
||||
return globalThis?.crypto?.subtle;
|
||||
}
|
||||
async function pbkdf2Sha512Subtle(subtle, secret, salt, iterations, keylen) {
|
||||
(0, utils_1.assert)(subtle, "Argument subtle is falsy");
|
||||
(0, utils_1.assert)(typeof subtle === "object", "Argument subtle is not of type object");
|
||||
(0, utils_1.assert)(typeof subtle.importKey === "function", "subtle.importKey is not a function");
|
||||
(0, utils_1.assert)(typeof subtle.deriveBits === "function", "subtle.deriveBits is not a function");
|
||||
return subtle.importKey("raw", secret, { name: "PBKDF2" }, false, ["deriveBits"]).then((key) => subtle
|
||||
.deriveBits({
|
||||
name: "PBKDF2",
|
||||
salt: salt,
|
||||
iterations: iterations,
|
||||
hash: { name: "SHA-512" },
|
||||
}, key, keylen * 8)
|
||||
.then((buffer) => new Uint8Array(buffer)));
|
||||
}
|
||||
async function pbkdf2Sha512Noble(secret, salt, iterations, keylen) {
|
||||
return (0, pbkdf2_js_1.pbkdf2Async)(sha2_js_1.sha512, secret, salt, { c: iterations, dkLen: keylen });
|
||||
}
|
||||
/**
|
||||
* A pbkdf2 implementation for BIP39. This is not exported at package level and thus a private API.
|
||||
*/
|
||||
async function pbkdf2Sha512(secret, salt, iterations, keylen) {
|
||||
const subtle = await getSubtle();
|
||||
if (subtle) {
|
||||
return pbkdf2Sha512Subtle(subtle, secret, salt, iterations, keylen);
|
||||
}
|
||||
else {
|
||||
return pbkdf2Sha512Noble(secret, salt, iterations, keylen);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=pbkdf2.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"pbkdf2.js","sourceRoot":"","sources":["../src/pbkdf2.ts"],"names":[],"mappings":";;AAWA,8BAQC;AAED,gDA0BC;AAED,8CAOC;AAKD,oCAYC;AAzED,yCAAuC;AACvC,uDAA0E;AAC1E,mDAA8D;AAE9D;;;;;;GAMG;AACI,KAAK,UAAU,SAAS;IAC7B,iEAAiE;IACjE,gEAAgE;IAChE,oEAAoE;IACpE,qBAAqB;IACrB,mEAAmE;IACnE,mEAAmE;IACnE,OAAQ,UAAkB,EAAE,MAAM,EAAE,MAAM,CAAC;AAC7C,CAAC;AAEM,KAAK,UAAU,kBAAkB,CACtC,MAA4B,EAC5B,MAAkB,EAClB,IAAgB,EAChB,UAAkB,EAClB,MAAc;IAEd,IAAA,cAAM,EAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;IAC3C,IAAA,cAAM,EAAC,OAAO,MAAM,KAAK,QAAQ,EAAE,uCAAuC,CAAC,CAAC;IAC5E,IAAA,cAAM,EAAC,OAAO,MAAM,CAAC,SAAS,KAAK,UAAU,EAAE,oCAAoC,CAAC,CAAC;IACrF,IAAA,cAAM,EAAC,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,EAAE,qCAAqC,CAAC,CAAC;IAEvF,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAC7F,MAAM;SACH,UAAU,CACT;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,IAAI;QACV,UAAU,EAAE,UAAU;QACtB,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;KAC1B,EACD,GAAG,EACH,MAAM,GAAG,CAAC,CACX;SACA,IAAI,CAAC,CAAC,MAAmB,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CACzD,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,MAAkB,EAClB,IAAgB,EAChB,UAAkB,EAClB,MAAc;IAEd,OAAO,IAAA,uBAAgB,EAAC,gBAAW,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;AACvF,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,YAAY,CAChC,MAAkB,EAClB,IAAgB,EAChB,UAAkB,EAClB,MAAc;IAEd,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IACtE,CAAC;SAAM,CAAC;QACN,OAAO,iBAAiB,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC"}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
export declare class Random {
|
||||
/**
|
||||
* Returns `count` cryptographically secure random bytes
|
||||
*/
|
||||
static getBytes(count: number): Uint8Array;
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Random = void 0;
|
||||
class Random {
|
||||
/**
|
||||
* Returns `count` cryptographically secure random bytes
|
||||
*/
|
||||
static getBytes(count) {
|
||||
const out = new Uint8Array(count);
|
||||
globalThis.crypto.getRandomValues(out);
|
||||
return out;
|
||||
}
|
||||
}
|
||||
exports.Random = Random;
|
||||
//# sourceMappingURL=random.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"random.js","sourceRoot":"","sources":["../src/random.ts"],"names":[],"mappings":";;;AAAA,MAAa,MAAM;IACjB;;OAEG;IACI,MAAM,CAAC,QAAQ,CAAC,KAAa;QAClC,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;QAClC,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QACvC,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AATD,wBASC"}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
import { HashFunction } from "./hash";
|
||||
export declare class Ripemd160 implements HashFunction {
|
||||
readonly blockSize: number;
|
||||
private readonly impl;
|
||||
constructor(firstData?: Uint8Array);
|
||||
update(data: Uint8Array): this;
|
||||
digest(): Uint8Array;
|
||||
}
|
||||
/** Convenience function equivalent to `new Ripemd160(data).digest()` */
|
||||
export declare function ripemd160(data: Uint8Array): Uint8Array;
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Ripemd160 = void 0;
|
||||
exports.ripemd160 = ripemd160;
|
||||
const legacy_js_1 = require("@noble/hashes/legacy.js");
|
||||
const utils_1 = require("./utils");
|
||||
class Ripemd160 {
|
||||
blockSize = 512 / 8;
|
||||
impl = legacy_js_1.ripemd160.create();
|
||||
constructor(firstData) {
|
||||
if (firstData) {
|
||||
this.update(firstData);
|
||||
}
|
||||
}
|
||||
update(data) {
|
||||
this.impl.update((0, utils_1.toRealUint8Array)(data));
|
||||
return this;
|
||||
}
|
||||
digest() {
|
||||
return this.impl.digest();
|
||||
}
|
||||
}
|
||||
exports.Ripemd160 = Ripemd160;
|
||||
/** Convenience function equivalent to `new Ripemd160(data).digest()` */
|
||||
function ripemd160(data) {
|
||||
return new Ripemd160(data).digest();
|
||||
}
|
||||
//# sourceMappingURL=ripemd.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"ripemd.js","sourceRoot":"","sources":["../src/ripemd.ts"],"names":[],"mappings":";;;AA2BA,8BAEC;AA7BD,uDAAsE;AAGtE,mCAA2C;AAE3C,MAAa,SAAS;IACJ,SAAS,GAAG,GAAG,GAAG,CAAC,CAAC;IAEnB,IAAI,GAAG,qBAAc,CAAC,MAAM,EAAE,CAAC;IAEhD,YAAmB,SAAsB;QACvC,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,IAAgB;QAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAA,wBAAgB,EAAC,IAAI,CAAC,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;CACF;AAnBD,8BAmBC;AAED,wEAAwE;AACxE,SAAgB,SAAS,CAAC,IAAgB;IACxC,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;AACtC,CAAC"}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
import { ExtendedSecp256k1Signature, Secp256k1Signature } from "./secp256k1signature";
|
||||
export interface Secp256k1Keypair {
|
||||
/** A 32 byte private key */
|
||||
readonly pubkey: Uint8Array;
|
||||
/**
|
||||
* A raw secp256k1 public key.
|
||||
*
|
||||
* The type itself does not give you any guarantee if this is
|
||||
* compressed or uncompressed. If you are unsure where the data
|
||||
* is coming from, use `Secp256k1.compressPubkey` or
|
||||
* `Secp256k1.uncompressPubkey` (both idempotent) before processing it.
|
||||
*/
|
||||
readonly privkey: Uint8Array;
|
||||
}
|
||||
export declare class Secp256k1 {
|
||||
/**
|
||||
* Takes a 32 byte private key and returns a privkey/pubkey pair.
|
||||
*
|
||||
* The resulting pubkey is uncompressed. For the use in Cosmos it should
|
||||
* be compressed first using `Secp256k1.compressPubkey`.
|
||||
*/
|
||||
static makeKeypair(privkey: Uint8Array): Promise<Secp256k1Keypair>;
|
||||
/**
|
||||
* Creates a signature that is
|
||||
* - deterministic (RFC 6979)
|
||||
* - lowS signature
|
||||
* - DER encoded
|
||||
*/
|
||||
static createSignature(messageHash: Uint8Array, privkey: Uint8Array): Promise<ExtendedSecp256k1Signature>;
|
||||
static verifySignature(signature: Secp256k1Signature, messageHash: Uint8Array, pubkey: Uint8Array): Promise<boolean>;
|
||||
static recoverPubkey(signature: ExtendedSecp256k1Signature, messageHash: Uint8Array): Uint8Array;
|
||||
/**
|
||||
* Takes a compressed or uncompressed pubkey and return a compressed one.
|
||||
*
|
||||
* This function is idempotent.
|
||||
*/
|
||||
static compressPubkey(pubkey: Uint8Array): Uint8Array;
|
||||
/**
|
||||
* Takes a compressed or uncompressed pubkey and returns an uncompressed one.
|
||||
*
|
||||
* This function is idempotent.
|
||||
*/
|
||||
static uncompressPubkey(pubkey: Uint8Array): Uint8Array;
|
||||
static trimRecoveryByte(signature: Uint8Array): Uint8Array;
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Secp256k1 = void 0;
|
||||
const encoding_1 = require("@cosmjs/encoding");
|
||||
const utils_1 = require("@cosmjs/utils");
|
||||
const secp256k1_1 = require("@noble/curves/secp256k1");
|
||||
const secp256k1signature_1 = require("./secp256k1signature");
|
||||
function unsignedBigIntToBytes(a) {
|
||||
(0, utils_1.assert)(a >= 0n);
|
||||
let hex = a.toString(16);
|
||||
if (hex.length % 2)
|
||||
hex = "0" + hex;
|
||||
return (0, encoding_1.fromHex)(hex);
|
||||
}
|
||||
function bytesToUnsignedBigInt(a) {
|
||||
return BigInt("0x" + (0, encoding_1.toHex)(a));
|
||||
}
|
||||
class Secp256k1 {
|
||||
/**
|
||||
* Takes a 32 byte private key and returns a privkey/pubkey pair.
|
||||
*
|
||||
* The resulting pubkey is uncompressed. For the use in Cosmos it should
|
||||
* be compressed first using `Secp256k1.compressPubkey`.
|
||||
*/
|
||||
static async makeKeypair(privkey) {
|
||||
if (privkey.length !== 32) {
|
||||
throw new Error("input data is not a valid secp256k1 private key");
|
||||
}
|
||||
if (!secp256k1_1.secp256k1.utils.isValidPrivateKey(privkey)) {
|
||||
// not strictly smaller than N
|
||||
throw new Error("input data is not a valid secp256k1 private key");
|
||||
}
|
||||
const out = {
|
||||
privkey: privkey,
|
||||
// encodes uncompressed as
|
||||
// - 1-byte prefix "04"
|
||||
// - 32-byte x coordinate
|
||||
// - 32-byte y coordinate
|
||||
pubkey: secp256k1_1.secp256k1.getPublicKey(privkey, false),
|
||||
};
|
||||
return out;
|
||||
}
|
||||
/**
|
||||
* Creates a signature that is
|
||||
* - deterministic (RFC 6979)
|
||||
* - lowS signature
|
||||
* - DER encoded
|
||||
*/
|
||||
static async createSignature(messageHash, privkey) {
|
||||
if (messageHash.length === 0) {
|
||||
throw new Error("Message hash must not be empty");
|
||||
}
|
||||
if (messageHash.length > 32) {
|
||||
throw new Error("Message hash length must not exceed 32 bytes");
|
||||
}
|
||||
const { recovery, r, s } = secp256k1_1.secp256k1.sign(messageHash, privkey, {
|
||||
lowS: true,
|
||||
});
|
||||
if (typeof recovery !== "number")
|
||||
throw new Error("Recovery param missing");
|
||||
return new secp256k1signature_1.ExtendedSecp256k1Signature(unsignedBigIntToBytes(r), unsignedBigIntToBytes(s), recovery);
|
||||
}
|
||||
static async verifySignature(signature, messageHash, pubkey) {
|
||||
if (messageHash.length === 0) {
|
||||
throw new Error("Message hash must not be empty");
|
||||
}
|
||||
if (messageHash.length > 32) {
|
||||
throw new Error("Message hash length must not exceed 32 bytes");
|
||||
}
|
||||
const encodedSig = secp256k1_1.secp256k1.Signature.fromDER(signature.toDer());
|
||||
return secp256k1_1.secp256k1.verify(encodedSig, messageHash, pubkey, { lowS: false });
|
||||
}
|
||||
static recoverPubkey(signature, messageHash) {
|
||||
const pk = new secp256k1_1.secp256k1.Signature(bytesToUnsignedBigInt(signature.r()), bytesToUnsignedBigInt(signature.s()), signature.recovery).recoverPublicKey(messageHash);
|
||||
return pk.toBytes(false);
|
||||
}
|
||||
/**
|
||||
* Takes a compressed or uncompressed pubkey and return a compressed one.
|
||||
*
|
||||
* This function is idempotent.
|
||||
*/
|
||||
static compressPubkey(pubkey) {
|
||||
switch (pubkey.length) {
|
||||
case 33:
|
||||
return pubkey;
|
||||
case 65:
|
||||
return secp256k1_1.secp256k1.Point.fromBytes(pubkey).toBytes(true);
|
||||
default:
|
||||
throw new Error("Invalid pubkey length");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Takes a compressed or uncompressed pubkey and returns an uncompressed one.
|
||||
*
|
||||
* This function is idempotent.
|
||||
*/
|
||||
static uncompressPubkey(pubkey) {
|
||||
switch (pubkey.length) {
|
||||
case 33:
|
||||
return secp256k1_1.secp256k1.Point.fromBytes(pubkey).toBytes(false);
|
||||
case 65:
|
||||
return pubkey;
|
||||
default:
|
||||
throw new Error("Invalid pubkey length");
|
||||
}
|
||||
}
|
||||
static trimRecoveryByte(signature) {
|
||||
switch (signature.length) {
|
||||
case 64:
|
||||
return signature;
|
||||
case 65:
|
||||
return signature.slice(0, 64);
|
||||
default:
|
||||
throw new Error("Invalid signature length");
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.Secp256k1 = Secp256k1;
|
||||
//# sourceMappingURL=secp256k1.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"secp256k1.js","sourceRoot":"","sources":["../src/secp256k1.ts"],"names":[],"mappings":"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"}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
export declare class Secp256k1Signature {
|
||||
/**
|
||||
* Takes the pair of integers (r, s) as 2x32 byte of binary data.
|
||||
*
|
||||
* Note: This is the format Cosmos SDK uses natively.
|
||||
*
|
||||
* @param data a 64 byte value containing integers r and s.
|
||||
*/
|
||||
static fromFixedLength(data: Uint8Array): Secp256k1Signature;
|
||||
static fromDer(data: Uint8Array): Secp256k1Signature;
|
||||
private readonly data;
|
||||
constructor(r: Uint8Array, s: Uint8Array);
|
||||
r(length?: number): Uint8Array;
|
||||
s(length?: number): Uint8Array;
|
||||
toFixedLength(): Uint8Array;
|
||||
toDer(): Uint8Array;
|
||||
}
|
||||
/**
|
||||
* A Secp256k1Signature plus the recovery parameter
|
||||
*/
|
||||
export declare class ExtendedSecp256k1Signature extends Secp256k1Signature {
|
||||
/**
|
||||
* Decode extended signature from the simple fixed length encoding
|
||||
* described in toFixedLength().
|
||||
*/
|
||||
static fromFixedLength(data: Uint8Array): ExtendedSecp256k1Signature;
|
||||
readonly recovery: number;
|
||||
constructor(r: Uint8Array, s: Uint8Array, recovery: number);
|
||||
/**
|
||||
* A simple custom encoding that encodes the extended signature as
|
||||
* r (32 bytes) | s (32 bytes) | recovery param (1 byte)
|
||||
* where | denotes concatenation of bonary data.
|
||||
*/
|
||||
toFixedLength(): Uint8Array;
|
||||
}
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ExtendedSecp256k1Signature = exports.Secp256k1Signature = void 0;
|
||||
function trimLeadingNullBytes(inData) {
|
||||
let numberOfLeadingNullBytes = 0;
|
||||
for (const byte of inData) {
|
||||
if (byte === 0x00) {
|
||||
numberOfLeadingNullBytes++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return inData.slice(numberOfLeadingNullBytes);
|
||||
}
|
||||
const derTagInteger = 0x02;
|
||||
class Secp256k1Signature {
|
||||
/**
|
||||
* Takes the pair of integers (r, s) as 2x32 byte of binary data.
|
||||
*
|
||||
* Note: This is the format Cosmos SDK uses natively.
|
||||
*
|
||||
* @param data a 64 byte value containing integers r and s.
|
||||
*/
|
||||
static fromFixedLength(data) {
|
||||
if (data.length !== 64) {
|
||||
throw new Error(`Got invalid data length: ${data.length}. Expected 2x 32 bytes for the pair (r, s)`);
|
||||
}
|
||||
return new Secp256k1Signature(trimLeadingNullBytes(data.slice(0, 32)), trimLeadingNullBytes(data.slice(32, 64)));
|
||||
}
|
||||
static fromDer(data) {
|
||||
let pos = 0;
|
||||
if (data[pos++] !== 0x30) {
|
||||
throw new Error("Prefix 0x30 expected");
|
||||
}
|
||||
const bodyLength = data[pos++];
|
||||
if (data.length - pos !== bodyLength) {
|
||||
throw new Error("Data length mismatch detected");
|
||||
}
|
||||
// r
|
||||
const rTag = data[pos++];
|
||||
if (rTag !== derTagInteger) {
|
||||
throw new Error("INTEGER tag expected");
|
||||
}
|
||||
const rLength = data[pos++];
|
||||
if (rLength >= 0x80) {
|
||||
throw new Error("Decoding length values above 127 not supported");
|
||||
}
|
||||
const rData = data.slice(pos, pos + rLength);
|
||||
pos += rLength;
|
||||
// s
|
||||
const sTag = data[pos++];
|
||||
if (sTag !== derTagInteger) {
|
||||
throw new Error("INTEGER tag expected");
|
||||
}
|
||||
const sLength = data[pos++];
|
||||
if (sLength >= 0x80) {
|
||||
throw new Error("Decoding length values above 127 not supported");
|
||||
}
|
||||
const sData = data.slice(pos, pos + sLength);
|
||||
pos += sLength;
|
||||
return new Secp256k1Signature(
|
||||
// r/s data can contain leading 0 bytes to express integers being non-negative in DER
|
||||
trimLeadingNullBytes(rData), trimLeadingNullBytes(sData));
|
||||
}
|
||||
data;
|
||||
constructor(r, s) {
|
||||
if (r.length > 32 || r.length === 0 || r[0] === 0x00) {
|
||||
throw new Error("Unsigned integer r must be encoded as unpadded big endian.");
|
||||
}
|
||||
if (s.length > 32 || s.length === 0 || s[0] === 0x00) {
|
||||
throw new Error("Unsigned integer s must be encoded as unpadded big endian.");
|
||||
}
|
||||
this.data = {
|
||||
r: r,
|
||||
s: s,
|
||||
};
|
||||
}
|
||||
r(length) {
|
||||
if (length === undefined) {
|
||||
return this.data.r;
|
||||
}
|
||||
else {
|
||||
const paddingLength = length - this.data.r.length;
|
||||
if (paddingLength < 0) {
|
||||
throw new Error("Length too small to hold parameter r");
|
||||
}
|
||||
const padding = new Uint8Array(paddingLength);
|
||||
return new Uint8Array([...padding, ...this.data.r]);
|
||||
}
|
||||
}
|
||||
s(length) {
|
||||
if (length === undefined) {
|
||||
return this.data.s;
|
||||
}
|
||||
else {
|
||||
const paddingLength = length - this.data.s.length;
|
||||
if (paddingLength < 0) {
|
||||
throw new Error("Length too small to hold parameter s");
|
||||
}
|
||||
const padding = new Uint8Array(paddingLength);
|
||||
return new Uint8Array([...padding, ...this.data.s]);
|
||||
}
|
||||
}
|
||||
toFixedLength() {
|
||||
return new Uint8Array([...this.r(32), ...this.s(32)]);
|
||||
}
|
||||
toDer() {
|
||||
// DER supports negative integers but our data is unsigned. Thus we need to prepend
|
||||
// a leading 0 byte when the highest bit is set to differentiate negative values
|
||||
const rEncoded = this.data.r[0] >= 0x80 ? new Uint8Array([0, ...this.data.r]) : this.data.r;
|
||||
const sEncoded = this.data.s[0] >= 0x80 ? new Uint8Array([0, ...this.data.s]) : this.data.s;
|
||||
const rLength = rEncoded.length;
|
||||
const sLength = sEncoded.length;
|
||||
const data = new Uint8Array([derTagInteger, rLength, ...rEncoded, derTagInteger, sLength, ...sEncoded]);
|
||||
return new Uint8Array([0x30, data.length, ...data]);
|
||||
}
|
||||
}
|
||||
exports.Secp256k1Signature = Secp256k1Signature;
|
||||
/**
|
||||
* A Secp256k1Signature plus the recovery parameter
|
||||
*/
|
||||
class ExtendedSecp256k1Signature extends Secp256k1Signature {
|
||||
/**
|
||||
* Decode extended signature from the simple fixed length encoding
|
||||
* described in toFixedLength().
|
||||
*/
|
||||
static fromFixedLength(data) {
|
||||
if (data.length !== 65) {
|
||||
throw new Error(`Got invalid data length ${data.length}. Expected 32 + 32 + 1`);
|
||||
}
|
||||
return new ExtendedSecp256k1Signature(trimLeadingNullBytes(data.slice(0, 32)), trimLeadingNullBytes(data.slice(32, 64)), data[64]);
|
||||
}
|
||||
recovery;
|
||||
constructor(r, s, recovery) {
|
||||
super(r, s);
|
||||
if (!Number.isInteger(recovery)) {
|
||||
throw new Error("The recovery parameter must be an integer.");
|
||||
}
|
||||
if (recovery < 0 || recovery > 4) {
|
||||
throw new Error("The recovery parameter must be one of 0, 1, 2, 3.");
|
||||
}
|
||||
this.recovery = recovery;
|
||||
}
|
||||
/**
|
||||
* A simple custom encoding that encodes the extended signature as
|
||||
* r (32 bytes) | s (32 bytes) | recovery param (1 byte)
|
||||
* where | denotes concatenation of bonary data.
|
||||
*/
|
||||
toFixedLength() {
|
||||
return new Uint8Array([...this.r(32), ...this.s(32), this.recovery]);
|
||||
}
|
||||
}
|
||||
exports.ExtendedSecp256k1Signature = ExtendedSecp256k1Signature;
|
||||
//# sourceMappingURL=secp256k1signature.js.map
|
||||
1
tools/mnemonic-test/node_modules/@cosmjs/crypto/build/secp256k1signature.js.map
generated
vendored
1
tools/mnemonic-test/node_modules/@cosmjs/crypto/build/secp256k1signature.js.map
generated
vendored
File diff suppressed because one or more lines are too long
|
|
@ -1,19 +0,0 @@
|
|||
import { HashFunction } from "./hash";
|
||||
export declare class Sha256 implements HashFunction {
|
||||
readonly blockSize: number;
|
||||
private readonly impl;
|
||||
constructor(firstData?: Uint8Array);
|
||||
update(data: Uint8Array): this;
|
||||
digest(): Uint8Array;
|
||||
}
|
||||
/** Convenience function equivalent to `new Sha256(data).digest()` */
|
||||
export declare function sha256(data: Uint8Array): Uint8Array;
|
||||
export declare class Sha512 implements HashFunction {
|
||||
readonly blockSize: number;
|
||||
private readonly impl;
|
||||
constructor(firstData?: Uint8Array);
|
||||
update(data: Uint8Array): this;
|
||||
digest(): Uint8Array;
|
||||
}
|
||||
/** Convenience function equivalent to `new Sha512(data).digest()` */
|
||||
export declare function sha512(data: Uint8Array): Uint8Array;
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Sha512 = exports.Sha256 = void 0;
|
||||
exports.sha256 = sha256;
|
||||
exports.sha512 = sha512;
|
||||
const sha2_js_1 = require("@noble/hashes/sha2.js");
|
||||
const utils_1 = require("./utils");
|
||||
class Sha256 {
|
||||
blockSize = 512 / 8;
|
||||
impl = sha2_js_1.sha256.create();
|
||||
constructor(firstData) {
|
||||
if (firstData) {
|
||||
this.update(firstData);
|
||||
}
|
||||
}
|
||||
update(data) {
|
||||
this.impl.update((0, utils_1.toRealUint8Array)(data));
|
||||
return this;
|
||||
}
|
||||
digest() {
|
||||
return this.impl.digest();
|
||||
}
|
||||
}
|
||||
exports.Sha256 = Sha256;
|
||||
/** Convenience function equivalent to `new Sha256(data).digest()` */
|
||||
function sha256(data) {
|
||||
return new Sha256(data).digest();
|
||||
}
|
||||
class Sha512 {
|
||||
blockSize = 1024 / 8;
|
||||
impl = sha2_js_1.sha512.create();
|
||||
constructor(firstData) {
|
||||
if (firstData) {
|
||||
this.update(firstData);
|
||||
}
|
||||
}
|
||||
update(data) {
|
||||
this.impl.update((0, utils_1.toRealUint8Array)(data));
|
||||
return this;
|
||||
}
|
||||
digest() {
|
||||
return this.impl.digest();
|
||||
}
|
||||
}
|
||||
exports.Sha512 = Sha512;
|
||||
/** Convenience function equivalent to `new Sha512(data).digest()` */
|
||||
function sha512(data) {
|
||||
return new Sha512(data).digest();
|
||||
}
|
||||
//# sourceMappingURL=sha.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"sha.js","sourceRoot":"","sources":["../src/sha.ts"],"names":[],"mappings":";;;AA2BA,wBAEC;AAwBD,wBAEC;AAvDD,mDAAqF;AAGrF,mCAA2C;AAE3C,MAAa,MAAM;IACD,SAAS,GAAG,GAAG,GAAG,CAAC,CAAC;IAEnB,IAAI,GAAG,gBAAW,CAAC,MAAM,EAAE,CAAC;IAE7C,YAAmB,SAAsB;QACvC,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,IAAgB;QAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAA,wBAAgB,EAAC,IAAI,CAAC,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;CACF;AAnBD,wBAmBC;AAED,qEAAqE;AACrE,SAAgB,MAAM,CAAC,IAAgB;IACrC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;AACnC,CAAC;AAED,MAAa,MAAM;IACD,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC;IAEpB,IAAI,GAAG,gBAAW,CAAC,MAAM,EAAE,CAAC;IAE7C,YAAmB,SAAsB;QACvC,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,IAAgB;QAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAA,wBAAgB,EAAC,IAAI,CAAC,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;CACF;AAnBD,wBAmBC;AAED,qEAAqE;AACrE,SAAgB,MAAM,CAAC,IAAgB;IACrC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;AACnC,CAAC"}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
import { Uint32 } from "@cosmjs/math";
|
||||
export interface Slip10Result {
|
||||
readonly chainCode: Uint8Array;
|
||||
readonly privkey: Uint8Array;
|
||||
}
|
||||
/**
|
||||
* Raw values must match the curve string in SLIP-0010 master key generation
|
||||
*
|
||||
* @see https://github.com/satoshilabs/slips/blob/master/slip-0010.md#master-key-generation
|
||||
*/
|
||||
export declare enum Slip10Curve {
|
||||
Secp256k1 = "Bitcoin seed",
|
||||
Ed25519 = "ed25519 seed"
|
||||
}
|
||||
/**
|
||||
* Reverse mapping of Slip10Curve
|
||||
*/
|
||||
export declare function slip10CurveFromString(curveString: string): Slip10Curve;
|
||||
export declare class Slip10RawIndex extends Uint32 {
|
||||
static hardened(hardenedIndex: number): Slip10RawIndex;
|
||||
static normal(normalIndex: number): Slip10RawIndex;
|
||||
isHardened(): boolean;
|
||||
}
|
||||
/**
|
||||
* An array of raw SLIP10 indices.
|
||||
*
|
||||
* This can be constructed via string parsing:
|
||||
*
|
||||
* ```ts
|
||||
* import { stringToPath } from "@cosmjs/crypto";
|
||||
*
|
||||
* const path = stringToPath("m/0'/1/2'/2/1000000000");
|
||||
* ```
|
||||
*
|
||||
* or manually:
|
||||
*
|
||||
* ```ts
|
||||
* import { HdPath, Slip10RawIndex } from "@cosmjs/crypto";
|
||||
*
|
||||
* // m/0'/1/2'/2/1000000000
|
||||
* const path: HdPath = [
|
||||
* Slip10RawIndex.hardened(0),
|
||||
* Slip10RawIndex.normal(1),
|
||||
* Slip10RawIndex.hardened(2),
|
||||
* Slip10RawIndex.normal(2),
|
||||
* Slip10RawIndex.normal(1000000000),
|
||||
* ];
|
||||
* ```
|
||||
*/
|
||||
export type HdPath = readonly Slip10RawIndex[];
|
||||
export declare class Slip10 {
|
||||
static derivePath(curve: Slip10Curve, seed: Uint8Array, path: HdPath): Slip10Result;
|
||||
private static master;
|
||||
private static child;
|
||||
/**
|
||||
* Implementation of ser_P(point(k_par)) from BIP-0032
|
||||
*
|
||||
* @see https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
|
||||
*/
|
||||
private static serializedPoint;
|
||||
private static childImpl;
|
||||
private static isZero;
|
||||
private static isGteN;
|
||||
private static n;
|
||||
}
|
||||
export declare function pathToString(path: HdPath): string;
|
||||
export declare function stringToPath(input: string): HdPath;
|
||||
|
|
@ -1,193 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Slip10 = exports.Slip10RawIndex = exports.Slip10Curve = void 0;
|
||||
exports.slip10CurveFromString = slip10CurveFromString;
|
||||
exports.pathToString = pathToString;
|
||||
exports.stringToPath = stringToPath;
|
||||
const encoding_1 = require("@cosmjs/encoding");
|
||||
const math_1 = require("@cosmjs/math");
|
||||
const utils_1 = require("@cosmjs/utils");
|
||||
const secp256k1_1 = require("@noble/curves/secp256k1");
|
||||
const hmac_1 = require("./hmac");
|
||||
const sha_1 = require("./sha");
|
||||
/**
|
||||
* Raw values must match the curve string in SLIP-0010 master key generation
|
||||
*
|
||||
* @see https://github.com/satoshilabs/slips/blob/master/slip-0010.md#master-key-generation
|
||||
*/
|
||||
var Slip10Curve;
|
||||
(function (Slip10Curve) {
|
||||
Slip10Curve["Secp256k1"] = "Bitcoin seed";
|
||||
Slip10Curve["Ed25519"] = "ed25519 seed";
|
||||
})(Slip10Curve || (exports.Slip10Curve = Slip10Curve = {}));
|
||||
function bytesToUnsignedBigInt(a) {
|
||||
return BigInt("0x" + (0, encoding_1.toHex)(a));
|
||||
}
|
||||
function intTo32be(n) {
|
||||
(0, utils_1.assert)(n >= 0n);
|
||||
(0, utils_1.assert)(n < 2n ** (32n * 8n));
|
||||
// 32 bytes is 64 hexadecimal characters
|
||||
const hex = n.toString(16).padStart(64, "0");
|
||||
return (0, encoding_1.fromHex)(hex);
|
||||
}
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */
|
||||
/**
|
||||
* Reverse mapping of Slip10Curve
|
||||
*/
|
||||
function slip10CurveFromString(curveString) {
|
||||
switch (curveString) {
|
||||
case Slip10Curve.Ed25519:
|
||||
return Slip10Curve.Ed25519;
|
||||
case Slip10Curve.Secp256k1:
|
||||
return Slip10Curve.Secp256k1;
|
||||
default:
|
||||
throw new Error(`Unknown curve string: '${curveString}'`);
|
||||
}
|
||||
}
|
||||
class Slip10RawIndex extends math_1.Uint32 {
|
||||
static hardened(hardenedIndex) {
|
||||
return new Slip10RawIndex(hardenedIndex + 2 ** 31);
|
||||
}
|
||||
static normal(normalIndex) {
|
||||
return new Slip10RawIndex(normalIndex);
|
||||
}
|
||||
isHardened() {
|
||||
return this.data >= 2 ** 31;
|
||||
}
|
||||
}
|
||||
exports.Slip10RawIndex = Slip10RawIndex;
|
||||
// Universal private key derivation according to
|
||||
// https://github.com/satoshilabs/slips/blob/master/slip-0010.md
|
||||
class Slip10 {
|
||||
static derivePath(curve, seed, path) {
|
||||
let result = this.master(curve, seed);
|
||||
for (const rawIndex of path) {
|
||||
result = this.child(curve, result.privkey, result.chainCode, rawIndex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static master(curve, seed) {
|
||||
const i = new hmac_1.Hmac(sha_1.Sha512, (0, encoding_1.toAscii)(curve)).update(seed).digest();
|
||||
const il = i.slice(0, 32);
|
||||
const ir = i.slice(32, 64);
|
||||
if (curve !== Slip10Curve.Ed25519 && (this.isZero(il) || this.isGteN(curve, il))) {
|
||||
return this.master(curve, i);
|
||||
}
|
||||
return {
|
||||
chainCode: ir,
|
||||
privkey: il,
|
||||
};
|
||||
}
|
||||
static child(curve, parentPrivkey, parentChainCode, rawIndex) {
|
||||
let i;
|
||||
if (rawIndex.isHardened()) {
|
||||
const payload = new Uint8Array([0x00, ...parentPrivkey, ...rawIndex.toBytesBigEndian()]);
|
||||
i = new hmac_1.Hmac(sha_1.Sha512, parentChainCode).update(payload).digest();
|
||||
}
|
||||
else {
|
||||
if (curve === Slip10Curve.Ed25519) {
|
||||
throw new Error("Normal keys are not allowed with ed25519");
|
||||
}
|
||||
else {
|
||||
// Step 1 of https://github.com/satoshilabs/slips/blob/master/slip-0010.md#private-parent-key--private-child-key
|
||||
// Calculate I = HMAC-SHA512(Key = c_par, Data = ser_P(point(k_par)) || ser_32(i)).
|
||||
// where the functions point() and ser_p() are defined in BIP-0032
|
||||
const data = new Uint8Array([
|
||||
...Slip10.serializedPoint(curve, bytesToUnsignedBigInt(parentPrivkey)),
|
||||
...rawIndex.toBytesBigEndian(),
|
||||
]);
|
||||
i = new hmac_1.Hmac(sha_1.Sha512, parentChainCode).update(data).digest();
|
||||
}
|
||||
}
|
||||
return this.childImpl(curve, parentPrivkey, parentChainCode, rawIndex, i);
|
||||
}
|
||||
/**
|
||||
* Implementation of ser_P(point(k_par)) from BIP-0032
|
||||
*
|
||||
* @see https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
|
||||
*/
|
||||
static serializedPoint(curve, p) {
|
||||
switch (curve) {
|
||||
case Slip10Curve.Secp256k1:
|
||||
return secp256k1_1.secp256k1.Point.BASE.multiply(p).toBytes(true);
|
||||
default:
|
||||
throw new Error("curve not supported");
|
||||
}
|
||||
}
|
||||
static childImpl(curve, parentPrivkey, parentChainCode, rawIndex, i) {
|
||||
// step 2 (of the Private parent key → private child key algorithm)
|
||||
const il = i.slice(0, 32);
|
||||
const ir = i.slice(32, 64);
|
||||
// step 3
|
||||
const returnChainCode = ir;
|
||||
// step 4
|
||||
if (curve === Slip10Curve.Ed25519) {
|
||||
return {
|
||||
chainCode: returnChainCode,
|
||||
privkey: il,
|
||||
};
|
||||
}
|
||||
// step 5
|
||||
const n = this.n(curve);
|
||||
const returnChildKeyAsNumber = (bytesToUnsignedBigInt(il) + bytesToUnsignedBigInt(parentPrivkey)) % n;
|
||||
const returnChildKey = intTo32be(returnChildKeyAsNumber);
|
||||
// step 6
|
||||
if (this.isGteN(curve, il) || this.isZero(returnChildKey)) {
|
||||
const newI = new hmac_1.Hmac(sha_1.Sha512, parentChainCode)
|
||||
.update(new Uint8Array([0x01, ...ir, ...rawIndex.toBytesBigEndian()]))
|
||||
.digest();
|
||||
return this.childImpl(curve, parentPrivkey, parentChainCode, rawIndex, newI);
|
||||
}
|
||||
// step 7
|
||||
return {
|
||||
chainCode: returnChainCode,
|
||||
privkey: returnChildKey,
|
||||
};
|
||||
}
|
||||
static isZero(privkey) {
|
||||
return privkey.every((byte) => byte === 0);
|
||||
}
|
||||
static isGteN(curve, privkey) {
|
||||
const keyAsNumber = bytesToUnsignedBigInt(privkey);
|
||||
return keyAsNumber >= this.n(curve);
|
||||
}
|
||||
static n(curve) {
|
||||
switch (curve) {
|
||||
case Slip10Curve.Secp256k1:
|
||||
return 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n;
|
||||
default:
|
||||
throw new Error("curve not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.Slip10 = Slip10;
|
||||
function pathToString(path) {
|
||||
return path.reduce((current, component) => {
|
||||
const componentString = component.isHardened()
|
||||
? `${component.toNumber() - 2 ** 31}'`
|
||||
: component.toString();
|
||||
return current + "/" + componentString;
|
||||
}, "m");
|
||||
}
|
||||
function stringToPath(input) {
|
||||
if (!input.startsWith("m"))
|
||||
throw new Error("Path string must start with 'm'");
|
||||
let rest = input.slice(1);
|
||||
const out = new Array();
|
||||
while (rest) {
|
||||
const match = rest.match(/^\/([0-9]+)('?)/);
|
||||
if (!match)
|
||||
throw new Error("Syntax error while reading path component");
|
||||
const [fullMatch, numberString, apostrophe] = match;
|
||||
const value = math_1.Uint53.fromString(numberString).toNumber();
|
||||
if (value >= 2 ** 31)
|
||||
throw new Error("Component value too high. Must not exceed 2**31-1.");
|
||||
if (apostrophe)
|
||||
out.push(Slip10RawIndex.hardened(value));
|
||||
else
|
||||
out.push(Slip10RawIndex.normal(value));
|
||||
rest = rest.slice(fullMatch.length);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
//# sourceMappingURL=slip10.js.map
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
|||
export declare function toRealUint8Array(data: ArrayLike<number>): Uint8Array;
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toRealUint8Array = toRealUint8Array;
|
||||
// See https://github.com/paulmillr/noble-hashes/issues/25 for why this is needed
|
||||
function toRealUint8Array(data) {
|
||||
if (data instanceof Uint8Array)
|
||||
return data;
|
||||
else
|
||||
return Uint8Array.from(data);
|
||||
}
|
||||
//# sourceMappingURL=utils.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;AACA,4CAGC;AAJD,iFAAiF;AACjF,SAAgB,gBAAgB,CAAC,IAAuB;IACtD,IAAI,IAAI,YAAY,UAAU;QAAE,OAAO,IAAI,CAAC;;QACvC,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC"}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
{
|
||||
"name": "@cosmjs/crypto",
|
||||
"version": "0.37.0",
|
||||
"description": "Cryptography resources for blockchain projects",
|
||||
"contributors": [
|
||||
"IOV SAS <admin@iov.one>",
|
||||
"Simon Warta"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"exports": {
|
||||
"types": "./build/index.d.ts",
|
||||
"default": "./build/index.js"
|
||||
},
|
||||
"files": [
|
||||
"build/",
|
||||
"*.md",
|
||||
"!*.spec.*",
|
||||
"!**/testdata/"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cosmos/cosmjs/tree/main/packages/crypto"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
},
|
||||
"scripts": {
|
||||
"docs": "typedoc",
|
||||
"format": "prettier --write --log-level warn \"./src/**/*.ts\"",
|
||||
"format-text": "prettier --write \"./*.md\"",
|
||||
"test-node": "yarn node jasmine-testrunner.cjs",
|
||||
"test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox karma.conf.cjs",
|
||||
"test-chrome": "yarn pack-web && karma start --single-run --browsers ChromeHeadless karma.conf.cjs",
|
||||
"test": "yarn build-or-skip && yarn test-node",
|
||||
"coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet",
|
||||
"build": "rm -rf ./build && tsc",
|
||||
"build-or-skip": "[ -n \"${SKIP_BUILD:-}\" ] || yarn build",
|
||||
"pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.cjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cosmjs/encoding": "^0.37.0",
|
||||
"@cosmjs/math": "^0.37.0",
|
||||
"@cosmjs/utils": "^0.37.0",
|
||||
"@noble/ciphers": "^1.3.0",
|
||||
"@noble/curves": "^1.9.2",
|
||||
"@noble/hashes": "^1.8.0",
|
||||
"@scure/bip39": "^1.6.0",
|
||||
"hash-wasm": "^4.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@istanbuljs/nyc-config-typescript": "^1.0.1",
|
||||
"@types/jasmine": "^4",
|
||||
"@types/karma-firefox-launcher": "^2",
|
||||
"@types/karma-jasmine": "^4",
|
||||
"@types/karma-jasmine-html-reporter": "^1",
|
||||
"@types/node": "*",
|
||||
"glob": "^11",
|
||||
"jasmine": "^4",
|
||||
"jasmine-spec-reporter": "^6",
|
||||
"karma": "^6.3.14",
|
||||
"karma-chrome-launcher": "^3.1.0",
|
||||
"karma-firefox-launcher": "^2.1.0",
|
||||
"karma-jasmine": "^5",
|
||||
"karma-jasmine-html-reporter": "^1.5.4",
|
||||
"nyc": "^17.1.0",
|
||||
"prettier": "^3.6.2",
|
||||
"ses": "^1.13.0",
|
||||
"source-map-support": "^0.5.19",
|
||||
"typedoc": "^0.28",
|
||||
"typescript": "~5.9",
|
||||
"webpack": "^5.76.0",
|
||||
"webpack-cli": "^4.6.0"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
# @cosmjs/encoding
|
||||
|
||||

|
||||
[](https://www.npmjs.com/package/@cosmjs/encoding)
|
||||
[](https://github.com/cosmos/cosmjs/blob/v0.35.0/LICENSE)
|
||||

|
||||

|
||||

|
||||
|
||||
This package is an extension to the JavaScript standard library that is not
|
||||
bound to blockchain products. It provides basic hex/base64/ascii encoding to
|
||||
Uint8Array that doesn't rely on Buffer and also provides better error messages
|
||||
on invalid input.
|
||||
|
||||
## Convert between bech32 and hex addresses
|
||||
|
||||
```
|
||||
>> toBech32("tiov", fromHex("1234ABCD0000AA0000FFFF0000AA00001234ABCD"))
|
||||
'tiov1zg62hngqqz4qqq8lluqqp2sqqqfrf27dzrrmea'
|
||||
>> toHex(fromBech32("tiov1zg62hngqqz4qqq8lluqqp2sqqqfrf27dzrrmea").data)
|
||||
'1234abcd0000aa0000ffff0000aa00001234abcd'
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This package is part of the cosmjs repository, licensed under the Apache License
|
||||
2.0 (see [NOTICE](https://github.com/cosmos/cosmjs/blob/main/NOTICE) and
|
||||
[LICENSE](https://github.com/cosmos/cosmjs/blob/main/LICENSE)).
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
export declare function toAscii(input: string): Uint8Array;
|
||||
export declare function fromAscii(data: Uint8Array): string;
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toAscii = toAscii;
|
||||
exports.fromAscii = fromAscii;
|
||||
function toAscii(input) {
|
||||
const toNums = (str) => str.split("").map((x) => {
|
||||
const charCode = x.charCodeAt(0);
|
||||
// 0x00–0x1F control characters
|
||||
// 0x20–0x7E printable characters
|
||||
// 0x7F delete character
|
||||
// 0x80–0xFF out of 7 bit ascii range
|
||||
if (charCode < 0x20 || charCode > 0x7e) {
|
||||
throw new Error(`Cannot encode character that is out of printable ASCII range: ${charCode}`);
|
||||
}
|
||||
return charCode;
|
||||
});
|
||||
return Uint8Array.from(toNums(input));
|
||||
}
|
||||
function fromAscii(data) {
|
||||
const fromNums = (listOfNumbers) => listOfNumbers.map((x) => {
|
||||
// 0x00–0x1F control characters
|
||||
// 0x20–0x7E printable characters
|
||||
// 0x7F delete character
|
||||
// 0x80–0xFF out of 7 bit ascii range
|
||||
if (x < 0x20 || x > 0x7e) {
|
||||
throw new Error(`Cannot decode character that is out of printable ASCII range: ${x}`);
|
||||
}
|
||||
return String.fromCharCode(x);
|
||||
});
|
||||
return fromNums(Array.from(data)).join("");
|
||||
}
|
||||
//# sourceMappingURL=ascii.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"ascii.js","sourceRoot":"","sources":["../src/ascii.ts"],"names":[],"mappings":";;AAAA,0BAcC;AAED,8BAcC;AA9BD,SAAgB,OAAO,CAAC,KAAa;IACnC,MAAM,MAAM,GAAG,CAAC,GAAW,EAAqB,EAAE,CAChD,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE;QAC9B,MAAM,QAAQ,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACjC,+BAA+B;QAC/B,iCAAiC;QACjC,wBAAwB;QACxB,qCAAqC;QACrC,IAAI,QAAQ,GAAG,IAAI,IAAI,QAAQ,GAAG,IAAI,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,iEAAiE,QAAQ,EAAE,CAAC,CAAC;QAC/F,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC,CAAC;IACL,OAAO,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,SAAgB,SAAS,CAAC,IAAgB;IACxC,MAAM,QAAQ,GAAG,CAAC,aAAgC,EAAqB,EAAE,CACvE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAS,EAAU,EAAE;QACtC,+BAA+B;QAC/B,iCAAiC;QACjC,wBAAwB;QACxB,qCAAqC;QACrC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,OAAO,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEL,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC7C,CAAC"}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
export declare function toBase64(data: Uint8Array): string;
|
||||
export declare function fromBase64(base64String: string): Uint8Array;
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toBase64 = toBase64;
|
||||
exports.fromBase64 = fromBase64;
|
||||
const base64js = __importStar(require("base64-js"));
|
||||
function toBase64(data) {
|
||||
return base64js.fromByteArray(data);
|
||||
}
|
||||
function fromBase64(base64String) {
|
||||
if (!base64String.match(/^[a-zA-Z0-9+/]*={0,2}$/)) {
|
||||
throw new Error("Invalid base64 string format");
|
||||
}
|
||||
return base64js.toByteArray(base64String);
|
||||
}
|
||||
//# sourceMappingURL=base64.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"base64.js","sourceRoot":"","sources":["../src/base64.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,4BAEC;AAED,gCAKC;AAXD,oDAAsC;AAEtC,SAAgB,QAAQ,CAAC,IAAgB;IACvC,OAAO,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAED,SAAgB,UAAU,CAAC,YAAoB;IAC7C,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,wBAAwB,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,QAAQ,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;AAC5C,CAAC"}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
export declare function toBech32(prefix: string, data: Uint8Array, limit?: number): string;
|
||||
export declare function fromBech32(address: string, limit?: number): {
|
||||
readonly prefix: string;
|
||||
readonly data: Uint8Array;
|
||||
};
|
||||
/**
|
||||
* Takes a bech32 address and returns a normalized (i.e. lower case) representation of it.
|
||||
*
|
||||
* The input is validated along the way, which makes this significantly safer than
|
||||
* using `address.toLowerCase()`.
|
||||
*/
|
||||
export declare function normalizeBech32(address: string): string;
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toBech32 = toBech32;
|
||||
exports.fromBech32 = fromBech32;
|
||||
exports.normalizeBech32 = normalizeBech32;
|
||||
const base_1 = require("@scure/base");
|
||||
function toBech32(prefix, data, limit) {
|
||||
const address = base_1.bech32.encode(prefix, base_1.bech32.toWords(data), limit);
|
||||
return address;
|
||||
}
|
||||
function hasBech32Separator(input) {
|
||||
return input.indexOf("1") !== -1;
|
||||
}
|
||||
function fromBech32(address, limit = Infinity) {
|
||||
// This extra check can be removed once
|
||||
// https://github.com/paulmillr/scure-base/pull/45 is merged and published.
|
||||
if (!hasBech32Separator(address))
|
||||
throw new Error(`No bech32 separator found`);
|
||||
const decodedAddress = base_1.bech32.decode(address, limit);
|
||||
return {
|
||||
prefix: decodedAddress.prefix,
|
||||
data: new Uint8Array(base_1.bech32.fromWords(decodedAddress.words)),
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Takes a bech32 address and returns a normalized (i.e. lower case) representation of it.
|
||||
*
|
||||
* The input is validated along the way, which makes this significantly safer than
|
||||
* using `address.toLowerCase()`.
|
||||
*/
|
||||
function normalizeBech32(address) {
|
||||
const { prefix, data } = fromBech32(address);
|
||||
return toBech32(prefix, data);
|
||||
}
|
||||
//# sourceMappingURL=bech32.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"bech32.js","sourceRoot":"","sources":["../src/bech32.ts"],"names":[],"mappings":";;AAEA,4BAGC;AAMD,gCAaC;AAQD,0CAGC;AAnCD,sCAAqC;AAErC,SAAgB,QAAQ,CAAC,MAAc,EAAE,IAAgB,EAAE,KAAc;IACvE,MAAM,OAAO,GAAG,aAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;IACnE,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa;IACvC,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AACnC,CAAC;AAED,SAAgB,UAAU,CACxB,OAAe,EACf,KAAK,GAAG,QAAQ;IAEhB,uCAAuC;IACvC,2EAA2E;IAC3E,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAE/E,MAAM,cAAc,GAAG,aAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrD,OAAO;QACL,MAAM,EAAE,cAAc,CAAC,MAAM;QAC7B,IAAI,EAAE,IAAI,UAAU,CAAC,aAAM,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;KAC7D,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAAC,OAAe;IAC7C,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC"}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
export declare function toHex(data: Uint8Array): string;
|
||||
export declare function fromHex(hexstring: string): Uint8Array;
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toHex = toHex;
|
||||
exports.fromHex = fromHex;
|
||||
function toHex(data) {
|
||||
let out = "";
|
||||
for (const byte of data) {
|
||||
out += ("0" + byte.toString(16)).slice(-2);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function fromHex(hexstring) {
|
||||
if (hexstring.length % 2 !== 0) {
|
||||
throw new Error("hex string length must be a multiple of 2");
|
||||
}
|
||||
const out = new Uint8Array(hexstring.length / 2);
|
||||
for (let i = 0; i < out.length; i++) {
|
||||
const j = 2 * i;
|
||||
const hexByteAsString = hexstring.slice(j, j + 2);
|
||||
if (!hexByteAsString.match(/[0-9a-f]{2}/i)) {
|
||||
throw new Error("hex string contains invalid characters");
|
||||
}
|
||||
out[i] = parseInt(hexByteAsString, 16);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
//# sourceMappingURL=hex.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"hex.js","sourceRoot":"","sources":["../src/hex.ts"],"names":[],"mappings":";;AAAA,sBAMC;AAED,0BAeC;AAvBD,SAAgB,KAAK,CAAC,IAAgB;IACpC,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAgB,OAAO,CAAC,SAAiB;IACvC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChB,MAAM,eAAe,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAClD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QACD,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
export { fromAscii, toAscii } from "./ascii";
|
||||
export { fromBase64, toBase64 } from "./base64";
|
||||
export { fromBech32, normalizeBech32, toBech32 } from "./bech32";
|
||||
export { fromHex, toHex } from "./hex";
|
||||
export { fromRfc3339, toRfc3339 } from "./rfc3339";
|
||||
export { fromUtf8, toUtf8 } from "./utf8";
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toUtf8 = exports.fromUtf8 = exports.toRfc3339 = exports.fromRfc3339 = exports.toHex = exports.fromHex = exports.toBech32 = exports.normalizeBech32 = exports.fromBech32 = exports.toBase64 = exports.fromBase64 = exports.toAscii = exports.fromAscii = void 0;
|
||||
var ascii_1 = require("./ascii");
|
||||
Object.defineProperty(exports, "fromAscii", { enumerable: true, get: function () { return ascii_1.fromAscii; } });
|
||||
Object.defineProperty(exports, "toAscii", { enumerable: true, get: function () { return ascii_1.toAscii; } });
|
||||
var base64_1 = require("./base64");
|
||||
Object.defineProperty(exports, "fromBase64", { enumerable: true, get: function () { return base64_1.fromBase64; } });
|
||||
Object.defineProperty(exports, "toBase64", { enumerable: true, get: function () { return base64_1.toBase64; } });
|
||||
var bech32_1 = require("./bech32");
|
||||
Object.defineProperty(exports, "fromBech32", { enumerable: true, get: function () { return bech32_1.fromBech32; } });
|
||||
Object.defineProperty(exports, "normalizeBech32", { enumerable: true, get: function () { return bech32_1.normalizeBech32; } });
|
||||
Object.defineProperty(exports, "toBech32", { enumerable: true, get: function () { return bech32_1.toBech32; } });
|
||||
var hex_1 = require("./hex");
|
||||
Object.defineProperty(exports, "fromHex", { enumerable: true, get: function () { return hex_1.fromHex; } });
|
||||
Object.defineProperty(exports, "toHex", { enumerable: true, get: function () { return hex_1.toHex; } });
|
||||
var rfc3339_1 = require("./rfc3339");
|
||||
Object.defineProperty(exports, "fromRfc3339", { enumerable: true, get: function () { return rfc3339_1.fromRfc3339; } });
|
||||
Object.defineProperty(exports, "toRfc3339", { enumerable: true, get: function () { return rfc3339_1.toRfc3339; } });
|
||||
var utf8_1 = require("./utf8");
|
||||
Object.defineProperty(exports, "fromUtf8", { enumerable: true, get: function () { return utf8_1.fromUtf8; } });
|
||||
Object.defineProperty(exports, "toUtf8", { enumerable: true, get: function () { return utf8_1.toUtf8; } });
|
||||
//# sourceMappingURL=index.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iCAA6C;AAApC,kGAAA,SAAS,OAAA;AAAE,gGAAA,OAAO,OAAA;AAC3B,mCAAgD;AAAvC,oGAAA,UAAU,OAAA;AAAE,kGAAA,QAAQ,OAAA;AAC7B,mCAAiE;AAAxD,oGAAA,UAAU,OAAA;AAAE,yGAAA,eAAe,OAAA;AAAE,kGAAA,QAAQ,OAAA;AAC9C,6BAAuC;AAA9B,8FAAA,OAAO,OAAA;AAAE,4FAAA,KAAK,OAAA;AACvB,qCAAmD;AAA1C,sGAAA,WAAW,OAAA;AAAE,oGAAA,SAAS,OAAA;AAC/B,+BAA0C;AAAjC,gGAAA,QAAQ,OAAA;AAAE,8FAAA,MAAM,OAAA"}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
import { ReadonlyDate } from "readonly-date";
|
||||
export declare function fromRfc3339(str: string): Date;
|
||||
export declare function toRfc3339(date: Date | ReadonlyDate): string;
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.fromRfc3339 = fromRfc3339;
|
||||
exports.toRfc3339 = toRfc3339;
|
||||
const rfc3339Matcher = /^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2}):(\d{2})(\.\d{1,9})?((?:[+-]\d{2}:\d{2})|Z)$/;
|
||||
function padded(integer, length = 2) {
|
||||
return integer.toString().padStart(length, "0");
|
||||
}
|
||||
function fromRfc3339(str) {
|
||||
const matches = rfc3339Matcher.exec(str);
|
||||
if (!matches) {
|
||||
throw new Error("Date string is not in RFC3339 format");
|
||||
}
|
||||
const year = +matches[1];
|
||||
const month = +matches[2];
|
||||
const day = +matches[3];
|
||||
const hour = +matches[4];
|
||||
const minute = +matches[5];
|
||||
const second = +matches[6];
|
||||
// fractional seconds match either undefined or a string like ".1", ".123456789"
|
||||
const milliSeconds = matches[7] ? Math.floor(+matches[7] * 1000) : 0;
|
||||
let tzOffsetSign;
|
||||
let tzOffsetHours;
|
||||
let tzOffsetMinutes;
|
||||
// if timezone is undefined, it must be Z or nothing (otherwise the group would have captured).
|
||||
if (matches[8] === "Z") {
|
||||
tzOffsetSign = 1;
|
||||
tzOffsetHours = 0;
|
||||
tzOffsetMinutes = 0;
|
||||
}
|
||||
else {
|
||||
tzOffsetSign = matches[8].substring(0, 1) === "-" ? -1 : 1;
|
||||
tzOffsetHours = +matches[8].substring(1, 3);
|
||||
tzOffsetMinutes = +matches[8].substring(4, 6);
|
||||
}
|
||||
const tzOffset = tzOffsetSign * (tzOffsetHours * 60 + tzOffsetMinutes) * 60; // seconds
|
||||
const date = new Date();
|
||||
date.setUTCFullYear(year, month - 1, day);
|
||||
date.setUTCHours(hour, minute, second, milliSeconds);
|
||||
return new Date(date.getTime() - tzOffset * 1000);
|
||||
}
|
||||
function toRfc3339(date) {
|
||||
const year = date.getUTCFullYear();
|
||||
const month = padded(date.getUTCMonth() + 1);
|
||||
const day = padded(date.getUTCDate());
|
||||
const hour = padded(date.getUTCHours());
|
||||
const minute = padded(date.getUTCMinutes());
|
||||
const second = padded(date.getUTCSeconds());
|
||||
const ms = padded(date.getUTCMilliseconds(), 3);
|
||||
return `${year}-${month}-${day}T${hour}:${minute}:${second}.${ms}Z`;
|
||||
}
|
||||
//# sourceMappingURL=rfc3339.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"rfc3339.js","sourceRoot":"","sources":["../src/rfc3339.ts"],"names":[],"mappings":"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"}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
export declare function toUtf8(str: string): Uint8Array;
|
||||
/**
|
||||
* Takes UTF-8 data and decodes it to a string.
|
||||
*
|
||||
* In lossy mode, the [REPLACEMENT CHARACTER](https://en.wikipedia.org/wiki/Specials_(Unicode_block))
|
||||
* is used to substitute invalid encodings.
|
||||
* By default lossy mode is off and invalid data will lead to exceptions.
|
||||
*/
|
||||
export declare function fromUtf8(data: Uint8Array, lossy?: boolean): string;
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toUtf8 = toUtf8;
|
||||
exports.fromUtf8 = fromUtf8;
|
||||
function toUtf8(str) {
|
||||
return new TextEncoder().encode(str);
|
||||
}
|
||||
/**
|
||||
* Takes UTF-8 data and decodes it to a string.
|
||||
*
|
||||
* In lossy mode, the [REPLACEMENT CHARACTER](https://en.wikipedia.org/wiki/Specials_(Unicode_block))
|
||||
* is used to substitute invalid encodings.
|
||||
* By default lossy mode is off and invalid data will lead to exceptions.
|
||||
*/
|
||||
function fromUtf8(data, lossy = false) {
|
||||
const fatal = !lossy;
|
||||
return new TextDecoder("utf-8", { fatal }).decode(data);
|
||||
}
|
||||
//# sourceMappingURL=utf8.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"utf8.js","sourceRoot":"","sources":["../src/utf8.ts"],"names":[],"mappings":";;AAAA,wBAEC;AASD,4BAGC;AAdD,SAAgB,MAAM,CAAC,GAAW;IAChC,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,QAAQ,CAAC,IAAgB,EAAE,KAAK,GAAG,KAAK;IACtD,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC;IACrB,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC1D,CAAC"}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
{
|
||||
"name": "@cosmjs/encoding",
|
||||
"version": "0.37.0",
|
||||
"description": "Encoding helpers for blockchain projects",
|
||||
"contributors": [
|
||||
"IOV SAS <admin@iov.one>"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"exports": {
|
||||
"types": "./build/index.d.ts",
|
||||
"default": "./build/index.js"
|
||||
},
|
||||
"files": [
|
||||
"build/",
|
||||
"*.md",
|
||||
"!*.spec.*",
|
||||
"!**/testdata/"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cosmos/cosmjs/tree/main/packages/encoding"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
},
|
||||
"scripts": {
|
||||
"docs": "typedoc",
|
||||
"format": "prettier --write --log-level warn \"./src/**/*.ts\"",
|
||||
"format-text": "prettier --write \"./*.md\"",
|
||||
"test-node": "yarn node jasmine-testrunner.cjs",
|
||||
"test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox karma.conf.cjs",
|
||||
"test-chrome": "yarn pack-web && karma start --single-run --browsers ChromeHeadless karma.conf.cjs",
|
||||
"test": "yarn build-or-skip && yarn test-node",
|
||||
"coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet",
|
||||
"build": "rm -rf ./build && tsc",
|
||||
"build-or-skip": "[ -n \"${SKIP_BUILD:-}\" ] || yarn build",
|
||||
"pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.cjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@scure/base": "^2.0.0",
|
||||
"base64-js": "^1.3.0",
|
||||
"readonly-date": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@istanbuljs/nyc-config-typescript": "^1.0.1",
|
||||
"@types/base64-js": "^1.2.5",
|
||||
"@types/jasmine": "^4",
|
||||
"@types/karma-firefox-launcher": "^2",
|
||||
"@types/karma-jasmine": "^4",
|
||||
"@types/karma-jasmine-html-reporter": "^1",
|
||||
"@types/node": "*",
|
||||
"glob": "^11",
|
||||
"jasmine": "^4",
|
||||
"jasmine-spec-reporter": "^6",
|
||||
"karma": "^6.3.14",
|
||||
"karma-chrome-launcher": "^3.1.0",
|
||||
"karma-firefox-launcher": "^2.1.0",
|
||||
"karma-jasmine": "^5",
|
||||
"karma-jasmine-html-reporter": "^1.5.4",
|
||||
"nyc": "^17.1.0",
|
||||
"prettier": "^3.6.2",
|
||||
"ses": "^1.13.0",
|
||||
"source-map-support": "^0.5.19",
|
||||
"typedoc": "^0.28",
|
||||
"typescript": "~5.9",
|
||||
"webpack": "^5.76.0",
|
||||
"webpack-cli": "^4.6.0"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
# @cosmjs/math
|
||||
|
||||

|
||||
[](https://www.npmjs.com/package/@cosmjs/math)
|
||||
[](https://github.com/cosmos/cosmjs/blob/v0.35.0/LICENSE)
|
||||

|
||||

|
||||

|
||||
|
||||
## License
|
||||
|
||||
This package is part of the cosmjs repository, licensed under the Apache License
|
||||
2.0 (see [NOTICE](https://github.com/cosmos/cosmjs/blob/main/NOTICE) and
|
||||
[LICENSE](https://github.com/cosmos/cosmjs/blob/main/LICENSE)).
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
import { Uint32, Uint53, Uint64 } from "./integers";
|
||||
/**
|
||||
* A type for arbitrary precision, non-negative decimals.
|
||||
*
|
||||
* Instances of this class are immutable.
|
||||
*/
|
||||
export declare class Decimal {
|
||||
static fromUserInput(input: string, fractionalDigits: number): Decimal;
|
||||
static fromAtomics(atomics: string, fractionalDigits: number): Decimal;
|
||||
/**
|
||||
* Creates a Decimal with value 0.0 and the given number of fractional digits.
|
||||
*
|
||||
* Fractional digits are not relevant for the value but needed to be able
|
||||
* to perform arithmetic operations with other decimals.
|
||||
*/
|
||||
static zero(fractionalDigits: number): Decimal;
|
||||
/**
|
||||
* Creates a Decimal with value 1.0 and the given number of fractional digits.
|
||||
*
|
||||
* Fractional digits are not relevant for the value but needed to be able
|
||||
* to perform arithmetic operations with other decimals.
|
||||
*/
|
||||
static one(fractionalDigits: number): Decimal;
|
||||
private static verifyFractionalDigits;
|
||||
static compare(a: Decimal, b: Decimal): number;
|
||||
get atomics(): string;
|
||||
get fractionalDigits(): number;
|
||||
private readonly data;
|
||||
private constructor();
|
||||
/** Creates a new instance with the same value */
|
||||
private clone;
|
||||
/** Returns the greatest decimal <= this which has no fractional part (rounding down) */
|
||||
floor(): Decimal;
|
||||
/** Returns the smallest decimal >= this which has no fractional part (rounding up) */
|
||||
ceil(): Decimal;
|
||||
toString(): string;
|
||||
/**
|
||||
* Returns an approximation as a float type. Only use this if no
|
||||
* exact calculation is required.
|
||||
*/
|
||||
toFloatApproximation(): number;
|
||||
/**
|
||||
* a.plus(b) returns a+b.
|
||||
*
|
||||
* Both values need to have the same fractional digits.
|
||||
*/
|
||||
plus(b: Decimal): Decimal;
|
||||
/**
|
||||
* a.minus(b) returns a-b.
|
||||
*
|
||||
* Both values need to have the same fractional digits.
|
||||
* The resulting difference needs to be non-negative.
|
||||
*/
|
||||
minus(b: Decimal): Decimal;
|
||||
/**
|
||||
* a.multiply(b) returns a*b.
|
||||
*
|
||||
* We only allow multiplication by unsigned integers to avoid rounding errors.
|
||||
*/
|
||||
multiply(b: Uint32 | Uint53 | Uint64): Decimal;
|
||||
equals(b: Decimal): boolean;
|
||||
isLessThan(b: Decimal): boolean;
|
||||
isLessThanOrEqual(b: Decimal): boolean;
|
||||
isGreaterThan(b: Decimal): boolean;
|
||||
isGreaterThanOrEqual(b: Decimal): boolean;
|
||||
}
|
||||
|
|
@ -1,214 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Decimal = void 0;
|
||||
// Too large values lead to massive memory usage. Limit to something sensible.
|
||||
// The largest value we need is 18 (Ether).
|
||||
const maxFractionalDigits = 100;
|
||||
/**
|
||||
* A type for arbitrary precision, non-negative decimals.
|
||||
*
|
||||
* Instances of this class are immutable.
|
||||
*/
|
||||
class Decimal {
|
||||
static fromUserInput(input, fractionalDigits) {
|
||||
Decimal.verifyFractionalDigits(fractionalDigits);
|
||||
const badCharacter = input.match(/[^0-9.]/);
|
||||
if (badCharacter) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
throw new Error(`Invalid character at position ${badCharacter.index + 1}`);
|
||||
}
|
||||
let whole;
|
||||
let fractional;
|
||||
if (input === "") {
|
||||
whole = "0";
|
||||
fractional = "";
|
||||
}
|
||||
else if (input.search(/\./) === -1) {
|
||||
// integer format, no separator
|
||||
whole = input;
|
||||
fractional = "";
|
||||
}
|
||||
else {
|
||||
const parts = input.split(".");
|
||||
switch (parts.length) {
|
||||
case 0:
|
||||
case 1:
|
||||
throw new Error("Fewer than two elements in split result. This must not happen here.");
|
||||
case 2:
|
||||
if (!parts[1])
|
||||
throw new Error("Fractional part missing");
|
||||
whole = parts[0];
|
||||
fractional = parts[1].replace(/0+$/, "");
|
||||
break;
|
||||
default:
|
||||
throw new Error("More than one separator found");
|
||||
}
|
||||
}
|
||||
if (fractional.length > fractionalDigits) {
|
||||
throw new Error("Got more fractional digits than supported");
|
||||
}
|
||||
const quantity = `${whole}${fractional.padEnd(fractionalDigits, "0")}`;
|
||||
return new Decimal(quantity, fractionalDigits);
|
||||
}
|
||||
static fromAtomics(atomics, fractionalDigits) {
|
||||
Decimal.verifyFractionalDigits(fractionalDigits);
|
||||
return new Decimal(atomics, fractionalDigits);
|
||||
}
|
||||
/**
|
||||
* Creates a Decimal with value 0.0 and the given number of fractional digits.
|
||||
*
|
||||
* Fractional digits are not relevant for the value but needed to be able
|
||||
* to perform arithmetic operations with other decimals.
|
||||
*/
|
||||
static zero(fractionalDigits) {
|
||||
Decimal.verifyFractionalDigits(fractionalDigits);
|
||||
return new Decimal("0", fractionalDigits);
|
||||
}
|
||||
/**
|
||||
* Creates a Decimal with value 1.0 and the given number of fractional digits.
|
||||
*
|
||||
* Fractional digits are not relevant for the value but needed to be able
|
||||
* to perform arithmetic operations with other decimals.
|
||||
*/
|
||||
static one(fractionalDigits) {
|
||||
Decimal.verifyFractionalDigits(fractionalDigits);
|
||||
return new Decimal("1" + "0".repeat(fractionalDigits), fractionalDigits);
|
||||
}
|
||||
static verifyFractionalDigits(fractionalDigits) {
|
||||
if (!Number.isInteger(fractionalDigits))
|
||||
throw new Error("Fractional digits is not an integer");
|
||||
if (fractionalDigits < 0)
|
||||
throw new Error("Fractional digits must not be negative");
|
||||
if (fractionalDigits > maxFractionalDigits) {
|
||||
throw new Error(`Fractional digits must not exceed ${maxFractionalDigits}`);
|
||||
}
|
||||
}
|
||||
static compare(a, b) {
|
||||
if (a.fractionalDigits !== b.fractionalDigits)
|
||||
throw new Error("Fractional digits do not match");
|
||||
const difference = a.data.atomics - b.data.atomics;
|
||||
if (difference < 0n)
|
||||
return -1;
|
||||
if (difference > 0n)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
get atomics() {
|
||||
return this.data.atomics.toString();
|
||||
}
|
||||
get fractionalDigits() {
|
||||
return this.data.fractionalDigits;
|
||||
}
|
||||
data;
|
||||
constructor(atomics, fractionalDigits) {
|
||||
if (!atomics.match(/^[0-9]+$/)) {
|
||||
throw new Error("Invalid string format. Only non-negative integers in decimal representation supported.");
|
||||
}
|
||||
this.data = {
|
||||
atomics: BigInt(atomics),
|
||||
fractionalDigits: fractionalDigits,
|
||||
};
|
||||
}
|
||||
/** Creates a new instance with the same value */
|
||||
clone() {
|
||||
return new Decimal(this.atomics, this.fractionalDigits);
|
||||
}
|
||||
/** Returns the greatest decimal <= this which has no fractional part (rounding down) */
|
||||
floor() {
|
||||
const factor = 10n ** BigInt(this.data.fractionalDigits);
|
||||
const whole = this.data.atomics / factor;
|
||||
const fractional = this.data.atomics % factor;
|
||||
if (fractional === 0n) {
|
||||
return this.clone();
|
||||
}
|
||||
else {
|
||||
return Decimal.fromAtomics((whole * factor).toString(), this.fractionalDigits);
|
||||
}
|
||||
}
|
||||
/** Returns the smallest decimal >= this which has no fractional part (rounding up) */
|
||||
ceil() {
|
||||
const factor = 10n ** BigInt(this.data.fractionalDigits);
|
||||
const whole = this.data.atomics / factor;
|
||||
const fractional = this.data.atomics % factor;
|
||||
if (fractional === 0n) {
|
||||
return this.clone();
|
||||
}
|
||||
else {
|
||||
return Decimal.fromAtomics(((whole + 1n) * factor).toString(), this.fractionalDigits);
|
||||
}
|
||||
}
|
||||
toString() {
|
||||
const factor = 10n ** BigInt(this.data.fractionalDigits);
|
||||
const whole = this.data.atomics / factor;
|
||||
const fractional = this.data.atomics % factor;
|
||||
if (fractional === 0n) {
|
||||
return whole.toString();
|
||||
}
|
||||
else {
|
||||
const fullFractionalPart = fractional.toString().padStart(this.data.fractionalDigits, "0");
|
||||
const trimmedFractionalPart = fullFractionalPart.replace(/0+$/, "");
|
||||
return `${whole.toString()}.${trimmedFractionalPart}`;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns an approximation as a float type. Only use this if no
|
||||
* exact calculation is required.
|
||||
*/
|
||||
toFloatApproximation() {
|
||||
const out = Number(this.toString());
|
||||
if (Number.isNaN(out))
|
||||
throw new Error("Conversion to number failed");
|
||||
return out;
|
||||
}
|
||||
/**
|
||||
* a.plus(b) returns a+b.
|
||||
*
|
||||
* Both values need to have the same fractional digits.
|
||||
*/
|
||||
plus(b) {
|
||||
if (this.fractionalDigits !== b.fractionalDigits)
|
||||
throw new Error("Fractional digits do not match");
|
||||
const sum = this.data.atomics + b.data.atomics;
|
||||
return new Decimal(sum.toString(), this.fractionalDigits);
|
||||
}
|
||||
/**
|
||||
* a.minus(b) returns a-b.
|
||||
*
|
||||
* Both values need to have the same fractional digits.
|
||||
* The resulting difference needs to be non-negative.
|
||||
*/
|
||||
minus(b) {
|
||||
if (this.fractionalDigits !== b.fractionalDigits)
|
||||
throw new Error("Fractional digits do not match");
|
||||
const difference = this.data.atomics - b.data.atomics;
|
||||
if (difference < 0n)
|
||||
throw new Error("Difference must not be negative");
|
||||
return new Decimal(difference.toString(), this.fractionalDigits);
|
||||
}
|
||||
/**
|
||||
* a.multiply(b) returns a*b.
|
||||
*
|
||||
* We only allow multiplication by unsigned integers to avoid rounding errors.
|
||||
*/
|
||||
multiply(b) {
|
||||
const product = this.data.atomics * b.toBigInt();
|
||||
return new Decimal(product.toString(), this.fractionalDigits);
|
||||
}
|
||||
equals(b) {
|
||||
return Decimal.compare(this, b) === 0;
|
||||
}
|
||||
isLessThan(b) {
|
||||
return Decimal.compare(this, b) < 0;
|
||||
}
|
||||
isLessThanOrEqual(b) {
|
||||
return Decimal.compare(this, b) <= 0;
|
||||
}
|
||||
isGreaterThan(b) {
|
||||
return Decimal.compare(this, b) > 0;
|
||||
}
|
||||
isGreaterThanOrEqual(b) {
|
||||
return Decimal.compare(this, b) >= 0;
|
||||
}
|
||||
}
|
||||
exports.Decimal = Decimal;
|
||||
//# sourceMappingURL=decimal.js.map
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,2 +0,0 @@
|
|||
export { Decimal } from "./decimal";
|
||||
export { Int53, Uint32, Uint53, Uint64 } from "./integers";
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Uint64 = exports.Uint53 = exports.Uint32 = exports.Int53 = exports.Decimal = void 0;
|
||||
var decimal_1 = require("./decimal");
|
||||
Object.defineProperty(exports, "Decimal", { enumerable: true, get: function () { return decimal_1.Decimal; } });
|
||||
var integers_1 = require("./integers");
|
||||
Object.defineProperty(exports, "Int53", { enumerable: true, get: function () { return integers_1.Int53; } });
|
||||
Object.defineProperty(exports, "Uint32", { enumerable: true, get: function () { return integers_1.Uint32; } });
|
||||
Object.defineProperty(exports, "Uint53", { enumerable: true, get: function () { return integers_1.Uint53; } });
|
||||
Object.defineProperty(exports, "Uint64", { enumerable: true, get: function () { return integers_1.Uint64; } });
|
||||
//# sourceMappingURL=index.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qCAAoC;AAA3B,kGAAA,OAAO,OAAA;AAChB,uCAA2D;AAAlD,iGAAA,KAAK,OAAA;AAAE,kGAAA,MAAM,OAAA;AAAE,kGAAA,MAAM,OAAA;AAAE,kGAAA,MAAM,OAAA"}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
/** Internal interface to ensure all integer types can be used equally */
|
||||
interface Integer {
|
||||
readonly toNumber: () => number;
|
||||
readonly toBigInt: () => bigint;
|
||||
readonly toString: () => string;
|
||||
}
|
||||
interface WithByteConverters {
|
||||
readonly toBytesBigEndian: () => Uint8Array;
|
||||
readonly toBytesLittleEndian: () => Uint8Array;
|
||||
}
|
||||
export declare class Uint32 implements Integer, WithByteConverters {
|
||||
/** @deprecated use Uint32.fromBytes */
|
||||
static fromBigEndianBytes(bytes: ArrayLike<number>): Uint32;
|
||||
/**
|
||||
* Creates a Uint32 from a fixed length byte array.
|
||||
*
|
||||
* @param bytes a list of exactly 4 bytes
|
||||
* @param endianness defaults to big endian
|
||||
*/
|
||||
static fromBytes(bytes: ArrayLike<number>, endianness?: "be" | "le"): Uint32;
|
||||
static fromString(str: string): Uint32;
|
||||
protected readonly data: number;
|
||||
constructor(input: number);
|
||||
toBytesBigEndian(): Uint8Array;
|
||||
toBytesLittleEndian(): Uint8Array;
|
||||
toNumber(): number;
|
||||
toBigInt(): bigint;
|
||||
toString(): string;
|
||||
}
|
||||
export declare class Int53 implements Integer {
|
||||
static fromString(str: string): Int53;
|
||||
protected readonly data: number;
|
||||
constructor(input: number);
|
||||
toNumber(): number;
|
||||
toBigInt(): bigint;
|
||||
toString(): string;
|
||||
}
|
||||
export declare class Uint53 implements Integer {
|
||||
static fromString(str: string): Uint53;
|
||||
protected readonly data: Int53;
|
||||
constructor(input: number);
|
||||
toNumber(): number;
|
||||
toBigInt(): bigint;
|
||||
toString(): string;
|
||||
}
|
||||
export declare class Uint64 implements Integer, WithByteConverters {
|
||||
/** @deprecated use Uint64.fromBytes */
|
||||
static fromBytesBigEndian(bytes: ArrayLike<number>): Uint64;
|
||||
/**
|
||||
* Creates a Uint64 from a fixed length byte array.
|
||||
*
|
||||
* @param bytes a list of exactly 8 bytes
|
||||
* @param endianness defaults to big endian
|
||||
*/
|
||||
static fromBytes(bytes: ArrayLike<number>, endianness?: "be" | "le"): Uint64;
|
||||
static fromString(str: string): Uint64;
|
||||
static fromNumber(input: number): Uint64;
|
||||
private readonly data;
|
||||
private constructor();
|
||||
toBytesBigEndian(): Uint8Array;
|
||||
toBytesLittleEndian(): Uint8Array;
|
||||
toString(): string;
|
||||
toBigInt(): bigint;
|
||||
toNumber(): number;
|
||||
}
|
||||
export {};
|
||||
|
|
@ -1,224 +0,0 @@
|
|||
"use strict";
|
||||
/* eslint-disable no-bitwise */
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Uint64 = exports.Uint53 = exports.Int53 = exports.Uint32 = void 0;
|
||||
const uint64MaxValue = 18446744073709551615n;
|
||||
class Uint32 {
|
||||
/** @deprecated use Uint32.fromBytes */
|
||||
static fromBigEndianBytes(bytes) {
|
||||
return Uint32.fromBytes(bytes);
|
||||
}
|
||||
/**
|
||||
* Creates a Uint32 from a fixed length byte array.
|
||||
*
|
||||
* @param bytes a list of exactly 4 bytes
|
||||
* @param endianness defaults to big endian
|
||||
*/
|
||||
static fromBytes(bytes, endianness = "be") {
|
||||
if (bytes.length !== 4) {
|
||||
throw new Error("Invalid input length. Expected 4 bytes.");
|
||||
}
|
||||
for (let i = 0; i < bytes.length; ++i) {
|
||||
if (!Number.isInteger(bytes[i]) || bytes[i] > 255 || bytes[i] < 0) {
|
||||
throw new Error(`Invalid value in byte. Found: ${bytes[i]}`);
|
||||
}
|
||||
}
|
||||
const beBytes = endianness === "be" ? bytes : Array.from(bytes).reverse();
|
||||
// Use multiplication instead of shifting since bitwise operators are defined
|
||||
// on SIGNED int32 in JavaScript and we don't want to risk surprises
|
||||
return new Uint32(beBytes[0] * 2 ** 24 + beBytes[1] * 2 ** 16 + beBytes[2] * 2 ** 8 + beBytes[3]);
|
||||
}
|
||||
static fromString(str) {
|
||||
if (!str.match(/^[0-9]+$/)) {
|
||||
throw new Error("Invalid string format");
|
||||
}
|
||||
return new Uint32(Number.parseInt(str, 10));
|
||||
}
|
||||
data;
|
||||
constructor(input) {
|
||||
if (Number.isNaN(input)) {
|
||||
throw new Error("Input is not a number");
|
||||
}
|
||||
if (!Number.isInteger(input)) {
|
||||
throw new Error("Input is not an integer");
|
||||
}
|
||||
if (input < 0 || input > 4294967295) {
|
||||
throw new Error("Input not in uint32 range: " + input.toString());
|
||||
}
|
||||
this.data = input;
|
||||
}
|
||||
toBytesBigEndian() {
|
||||
// Use division instead of shifting since bitwise operators are defined
|
||||
// on SIGNED int32 in JavaScript and we don't want to risk surprises
|
||||
return new Uint8Array([
|
||||
Math.floor(this.data / 2 ** 24) & 0xff,
|
||||
Math.floor(this.data / 2 ** 16) & 0xff,
|
||||
Math.floor(this.data / 2 ** 8) & 0xff,
|
||||
Math.floor(this.data / 2 ** 0) & 0xff,
|
||||
]);
|
||||
}
|
||||
toBytesLittleEndian() {
|
||||
// Use division instead of shifting since bitwise operators are defined
|
||||
// on SIGNED int32 in JavaScript and we don't want to risk surprises
|
||||
return new Uint8Array([
|
||||
Math.floor(this.data / 2 ** 0) & 0xff,
|
||||
Math.floor(this.data / 2 ** 8) & 0xff,
|
||||
Math.floor(this.data / 2 ** 16) & 0xff,
|
||||
Math.floor(this.data / 2 ** 24) & 0xff,
|
||||
]);
|
||||
}
|
||||
toNumber() {
|
||||
return this.data;
|
||||
}
|
||||
toBigInt() {
|
||||
return BigInt(this.toNumber());
|
||||
}
|
||||
toString() {
|
||||
return this.data.toString();
|
||||
}
|
||||
}
|
||||
exports.Uint32 = Uint32;
|
||||
class Int53 {
|
||||
static fromString(str) {
|
||||
if (!str.match(/^-?[0-9]+$/)) {
|
||||
throw new Error("Invalid string format");
|
||||
}
|
||||
return new Int53(Number.parseInt(str, 10));
|
||||
}
|
||||
data;
|
||||
constructor(input) {
|
||||
if (Number.isNaN(input)) {
|
||||
throw new Error("Input is not a number");
|
||||
}
|
||||
if (!Number.isInteger(input)) {
|
||||
throw new Error("Input is not an integer");
|
||||
}
|
||||
if (input < Number.MIN_SAFE_INTEGER || input > Number.MAX_SAFE_INTEGER) {
|
||||
throw new Error("Input not in int53 range: " + input.toString());
|
||||
}
|
||||
this.data = input;
|
||||
}
|
||||
toNumber() {
|
||||
return this.data;
|
||||
}
|
||||
toBigInt() {
|
||||
return BigInt(this.toNumber());
|
||||
}
|
||||
toString() {
|
||||
return this.data.toString();
|
||||
}
|
||||
}
|
||||
exports.Int53 = Int53;
|
||||
class Uint53 {
|
||||
static fromString(str) {
|
||||
const signed = Int53.fromString(str);
|
||||
return new Uint53(signed.toNumber());
|
||||
}
|
||||
data;
|
||||
constructor(input) {
|
||||
const signed = new Int53(input);
|
||||
if (signed.toNumber() < 0) {
|
||||
throw new Error("Input is negative");
|
||||
}
|
||||
this.data = signed;
|
||||
}
|
||||
toNumber() {
|
||||
return this.data.toNumber();
|
||||
}
|
||||
toBigInt() {
|
||||
return BigInt(this.toNumber());
|
||||
}
|
||||
toString() {
|
||||
return this.data.toString();
|
||||
}
|
||||
}
|
||||
exports.Uint53 = Uint53;
|
||||
class Uint64 {
|
||||
/** @deprecated use Uint64.fromBytes */
|
||||
static fromBytesBigEndian(bytes) {
|
||||
return Uint64.fromBytes(bytes);
|
||||
}
|
||||
/**
|
||||
* Creates a Uint64 from a fixed length byte array.
|
||||
*
|
||||
* @param bytes a list of exactly 8 bytes
|
||||
* @param endianness defaults to big endian
|
||||
*/
|
||||
static fromBytes(bytes, endianness = "be") {
|
||||
if (bytes.length !== 8) {
|
||||
throw new Error("Invalid input length. Expected 8 bytes.");
|
||||
}
|
||||
const beBytes = endianness === "be" ? Array.from(bytes) : Array.from(bytes).reverse();
|
||||
let value = 0n;
|
||||
for (const byte of beBytes) {
|
||||
value *= 256n;
|
||||
if (!Number.isInteger(byte) || byte > 255 || byte < 0) {
|
||||
throw new Error(`Invalid value in byte. Found: ${byte}`);
|
||||
}
|
||||
value += BigInt(byte);
|
||||
}
|
||||
return new Uint64(value);
|
||||
}
|
||||
static fromString(str) {
|
||||
if (!str.match(/^[0-9]+$/)) {
|
||||
throw new Error("Invalid string format");
|
||||
}
|
||||
return new Uint64(BigInt(str));
|
||||
}
|
||||
static fromNumber(input) {
|
||||
if (Number.isNaN(input)) {
|
||||
throw new Error("Input is not a number");
|
||||
}
|
||||
if (!Number.isInteger(input)) {
|
||||
throw new Error("Input is not an integer");
|
||||
}
|
||||
if (!Number.isSafeInteger(input)) {
|
||||
throw new Error("Input is not a safe integer");
|
||||
}
|
||||
const bigint = BigInt(input);
|
||||
return new Uint64(bigint);
|
||||
}
|
||||
data;
|
||||
constructor(data) {
|
||||
if (data < 0n) {
|
||||
throw new Error("Input is negative");
|
||||
}
|
||||
if (data > uint64MaxValue) {
|
||||
throw new Error("Input exceeds uint64 range");
|
||||
}
|
||||
this.data = data;
|
||||
}
|
||||
toBytesBigEndian() {
|
||||
return this.toBytesLittleEndian().reverse();
|
||||
}
|
||||
toBytesLittleEndian() {
|
||||
const bytes = new Uint8Array(8);
|
||||
let value = this.data;
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
bytes[i] = Number(value % 256n);
|
||||
value /= 256n;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
toString() {
|
||||
return this.data.toString(10);
|
||||
}
|
||||
toBigInt() {
|
||||
return this.data;
|
||||
}
|
||||
toNumber() {
|
||||
if (this.data > BigInt(Number.MAX_SAFE_INTEGER)) {
|
||||
throw new Error("number can only safely store up to 53 bits");
|
||||
}
|
||||
const num = Number(this.data);
|
||||
return num;
|
||||
}
|
||||
}
|
||||
exports.Uint64 = Uint64;
|
||||
// Assign classes to unused variables in order to verify static interface conformance at compile time.
|
||||
// Workaround for https://github.com/microsoft/TypeScript/issues/33892
|
||||
const _int53Class = Int53;
|
||||
const _uint53Class = Uint53;
|
||||
const _uint32Class = Uint32;
|
||||
const _uint64Class = Uint64;
|
||||
//# sourceMappingURL=integers.js.map
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,63 +0,0 @@
|
|||
{
|
||||
"name": "@cosmjs/math",
|
||||
"version": "0.37.0",
|
||||
"description": "Math helpers for blockchain projects",
|
||||
"contributors": [
|
||||
"IOV SAS <admin@iov.one>"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"exports": {
|
||||
"types": "./build/index.d.ts",
|
||||
"default": "./build/index.js"
|
||||
},
|
||||
"files": [
|
||||
"build/",
|
||||
"*.md",
|
||||
"!*.spec.*",
|
||||
"!**/testdata/"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cosmos/cosmjs/tree/main/packages/math"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
},
|
||||
"scripts": {
|
||||
"docs": "typedoc",
|
||||
"format": "prettier --write --log-level warn \"./src/**/*.ts\"",
|
||||
"format-text": "prettier --write \"./*.md\"",
|
||||
"test-node": "yarn node jasmine-testrunner.cjs",
|
||||
"test-firefox": "yarn pack-web && karma start --single-run --browsers Firefox karma.conf.cjs",
|
||||
"test-chrome": "yarn pack-web && karma start --single-run --browsers ChromeHeadless karma.conf.cjs",
|
||||
"test": "yarn build-or-skip && yarn test-node",
|
||||
"coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet",
|
||||
"build": "rm -rf ./build && tsc",
|
||||
"build-or-skip": "[ -n \"${SKIP_BUILD:-}\" ] || yarn build",
|
||||
"pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.cjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@istanbuljs/nyc-config-typescript": "^1.0.1",
|
||||
"@types/jasmine": "^4",
|
||||
"@types/karma-firefox-launcher": "^2",
|
||||
"@types/karma-jasmine": "^4",
|
||||
"@types/karma-jasmine-html-reporter": "^1",
|
||||
"glob": "^11",
|
||||
"jasmine": "^4",
|
||||
"jasmine-spec-reporter": "^6",
|
||||
"karma": "^6.3.14",
|
||||
"karma-chrome-launcher": "^3.1.0",
|
||||
"karma-firefox-launcher": "^2.1.0",
|
||||
"karma-jasmine": "^5",
|
||||
"karma-jasmine-html-reporter": "^1.5.4",
|
||||
"nyc": "^17.1.0",
|
||||
"prettier": "^3.6.2",
|
||||
"ses": "^1.13.0",
|
||||
"source-map-support": "^0.5.19",
|
||||
"typedoc": "^0.28",
|
||||
"typescript": "~5.9",
|
||||
"webpack": "^5.76.0",
|
||||
"webpack-cli": "^4.6.0"
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue