Files
smom-dbis-138/frontend-dapp/src/components/admin/WalletDeployment.tsx
zaragoza444 4919328162
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m18s
CI/CD Pipeline / Security Scanning (push) Successful in 2m53s
CI/CD Pipeline / Lint and Format (push) Failing after 49s
CI/CD Pipeline / Terraform Validation (push) Failing after 24s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 26s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 42s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 39s
Validation / validate-genesis (push) Successful in 33s
Validation / validate-terraform (push) Failing after 28s
Validation / validate-kubernetes (push) Failing after 12s
Validation / validate-smart-contracts (push) Failing after 13s
Validation / validate-security (push) Failing after 1m21s
Validation / validate-documentation (push) Failing after 22s
Verify Deployment / Verify Deployment (push) Failing after 1m0s
feat(swift): production listener config, MT202/910 outbound, activate scripts
2026-07-03 00:36:21 -07:00

181 lines
5.9 KiB
TypeScript

/**
* WalletDeployment Component - Deploy new Safe wallets for admin use
*/
import { useState } from 'react'
import { useAccount } from 'wagmi'
import { useAdmin } from '../../contexts/AdminContext'
import toast from 'react-hot-toast'
interface WalletConfig {
owners: string[]
threshold: number
name: string
}
export default function WalletDeployment() {
const { address } = useAccount()
const { addAuditLog } = useAdmin()
const [config, setConfig] = useState<WalletConfig>({
owners: address ? [address] : [],
threshold: 1,
name: '',
})
const [newOwner, setNewOwner] = useState('')
const [isDeploying, setIsDeploying] = useState(false)
const addOwner = () => {
if (!newOwner || !/^0x[a-fA-F0-9]{40}$/.test(newOwner)) {
toast.error('Invalid address')
return
}
if (config.owners.includes(newOwner)) {
toast.error('Owner already added')
return
}
setConfig((prev) => ({
...prev,
owners: [...prev.owners, newOwner],
}))
setNewOwner('')
}
const removeOwner = (owner: string) => {
if (config.owners.length <= 1) {
toast.error('Must have at least one owner')
return
}
setConfig((prev) => ({
...prev,
owners: prev.owners.filter((o) => o !== owner),
threshold: Math.min(prev.threshold, prev.owners.length - 1),
}))
}
const handleDeploy = async () => {
if (config.owners.length === 0) {
toast.error('Add at least one owner')
return
}
if (config.threshold > config.owners.length) {
toast.error('Threshold cannot exceed owner count')
return
}
if (!config.name) {
toast.error('Enter a wallet name')
return
}
setIsDeploying(true)
// Simulate deployment (in production, this would call Safe SDK)
setTimeout(() => {
toast.success(`Wallet "${config.name}" deployment initiated`)
addAuditLog({
user: address || 'admin',
action: 'deploy_wallet',
resourceType: 'wallet',
resourceId: `wallet_${Date.now()}`,
details: { name: config.name, owners: config.owners.length, threshold: config.threshold },
status: 'success',
})
setIsDeploying(false)
setConfig({
owners: address ? [address] : [],
threshold: 1,
name: '',
})
}, 2000)
}
return (
<div className="space-y-6">
<div className="bg-black/20 rounded-xl p-6 border border-white/10">
<h2 className="text-xl font-bold text-white mb-4">Deploy Safe Wallet</h2>
<p className="text-white/70 text-sm mb-4">
Deploy a new Gnosis Safe wallet for admin operations.
</p>
<div className="space-y-4">
<div>
<label className="block text-white/70 text-sm mb-2">Wallet Name</label>
<input
type="text"
value={config.name}
onChange={(e) => setConfig({ ...config, name: e.target.value })}
placeholder="My Admin Wallet"
className="w-full px-4 py-2 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/40 focus:outline-none focus:border-green-500"
/>
</div>
<div>
<label className="block text-white/70 text-sm mb-2">Owners</label>
<div className="space-y-2">
{config.owners.map((owner, index) => (
<div
key={index}
className="flex items-center justify-between bg-white/5 rounded-lg p-3"
>
<span className="text-white font-mono text-sm">{owner}</span>
{config.owners.length > 1 && (
<button
onClick={() => removeOwner(owner)}
className="text-red-400 hover:text-red-300 text-sm"
>
Remove
</button>
)}
</div>
))}
<div className="flex gap-2">
<input
type="text"
value={newOwner}
onChange={(e) => setNewOwner(e.target.value)}
placeholder="0x..."
className="flex-1 px-4 py-2 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/40 focus:outline-none focus:border-green-500 font-mono text-sm"
/>
<button
onClick={addOwner}
className="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg font-semibold transition-colors"
>
Add
</button>
</div>
</div>
</div>
<div>
<label className="block text-white/70 text-sm mb-2">
Threshold ({config.owners.length} owners)
</label>
<input
type="number"
value={config.threshold}
onChange={(e) =>
setConfig({
...config,
threshold: Math.max(1, Math.min(parseInt(e.target.value) || 1, config.owners.length)),
})
}
min="1"
max={config.owners.length}
className="w-full px-4 py-2 bg-white/10 border border-white/20 rounded-lg text-white focus:outline-none focus:border-green-500"
/>
<p className="text-white/60 text-xs mt-1">
Requires {config.threshold} of {config.owners.length} owners to approve transactions
</p>
</div>
<button
onClick={handleDeploy}
disabled={isDeploying || config.owners.length === 0 || !config.name}
className="w-full px-6 py-3 bg-green-600 hover:bg-green-700 disabled:bg-gray-600 disabled:cursor-not-allowed text-white rounded-lg font-semibold transition-colors"
>
{isDeploying ? 'Deploying...' : 'Deploy Wallet'}
</button>
</div>
</div>
</div>
)
}