Saltar al contenido
Safe Ops & Web3 Operations

Qué puede preparar el agente y dónde firma la persona en operaciones Safe

Un agente de IA puede preparar y comprobar una transacción Safe, pero las firmas que mueven los fondos deben quedarse en manos humanas.

Publicado Actualizado 14 min de lectura
SafemultisigAI agentsWeb3 opshuman approval

Este artículo es educativo y no sustituye una auditoría formal de smart contracts, asesoría legal, asesoría financiera ni una revisión de seguridad específica del protocolo.

Conectar un agente de IA a una tesorería cambia el trabajo: leer balances, decodificar llamadas y preparar transferencias no equivale a autorizar que los fondos se muevan. El límite entre preparar, firmar y ejecutar tienen que imponerlo las herramientas, las claves y las rutas de contrato a las que llega el agente de IA, no sus instrucciones.

Un cubo azul iluminado y un documento tras un panel de cristal; delante, una mano pulsa el botón naranja de un dispositivo de firma.
El agente prepara detrás del cristal; la firma se queda en la mano de la persona. Ilustración conceptual.

En Safe, una revisión de autoridad abarca más que owners y umbral: los módulos habilitados, el guard de transacciones y el hash EIP-712 exacto que aprueba cada firmante deciden quién puede mover fondos.

Para un equipo Web3 pequeño que opera un multisig, el resultado útil es un paquete que los firmantes puedan inspeccionar: qué se quiere hacer, en qué cadena, con qué contrato, bajo qué condiciones y con qué evidencia. La página de servicio describe el método a alto nivel; este artículo lo baja al nivel del operador, con los comandos que permiten comprobar cada pieza sin depender de la interfaz que la muestra.

¿Qué es el punto de firma y de permisos?

En un Safe multisig con un agente de IA, el punto de firma y de permisos es el límite técnico y operativo que separa el trabajo que puede preparar un agente de las acciones que autorizan las personas. Identifica quién propone, qué permisos tiene, qué transacción se revisa, quién firma y qué evidencia permite comprobar después lo que ocurrió.

La aprobación humana ya forma parte de arquitecturas documentadas; no es una idea nueva. La guía de Safe para acciones de agentes de IA propone que el agente sea uno de los firmantes, con umbrales como 2 de 3, 3 de 5 o 5 de 7, de modo que haga falta al menos una aprobación humana. Aquí elegimos una configuración más restringida: ninguna firma queda bajo la autoridad del agente. Es una decisión de diseño para este flujo operativo.

La diferencia tiene un coste y conviene verlo. Con el agente como firmante, el equipo ahorra una firma humana por operación, pero una clave en manos del agente pasa a formar parte de la autoridad del Safe. Además, si el agente es owner y es también quien envía la transacción, Safe cuenta su aprobación sin firma adicional: el tipo de firma de hash preaprobado acepta al owner que ejecuta. La firma delegada puede tener sentido en operaciones repetitivas y acotadas, pero entonces el límite debería vivir en un módulo o en un guard revisado por separado, no en las instrucciones del agente.

Para que el agente proponga sin ser owner, el Safe Transaction Service admite delegados: direcciones en las que un owner confía para publicar propuestas en su nombre. Una propuesta firmada por un delegado o por un owner se muestra en Safe Wallet; el resto se guarda en el servicio, pero no aparece. Un delegado no tiene autoridad on-chain: el contrato no cuenta su firma para el umbral, porque no es owner.

Cinco componentes que hacen revisable la preparación

Identidad distinta de la de los firmantes. El runtime del agente necesita una identidad operativa propia, con credenciales solo para las fuentes que debe consultar y, si propone transacciones, una dirección de delegado distinta de cualquier owner. Esa identidad permite atribuir una lectura o una preparación a una ejecución concreta. Las claves de los firmantes permanecen en sus wallets o sistemas de custodia, fuera del contexto y de las herramientas del agente.

Permisos definidos por operación. La política debe expresar acciones concretas: consultar una red determinada, leer el estado de un Safe, decodificar una llamada, simular contra un bloque fijado o publicar una propuesta. Conviene separar las herramientas de lectura, simulación y propuesta, y negar de forma explícita los métodos RPC que firman o envían. Una credencial amplia o una herramienta que acepta comandos arbitrarios requiere una revisión adicional de su alcance.

El siguiente fragmento es un ejemplo ilustrativo con un formato propio, no el esquema de ningún producto. Los nombres de los métodos RPC sí son los estándar de Ethereum y de las wallets.

yaml
# Política de herramientas del agente: ejemplo ilustrativo, formato propio
agent: treasury-preparer
chains: [1]                      # chainId permitidos
safes: ["0xSAFE..."]             # Safes que puede leer y para los que puede proponer
rpc:
  allow: [eth_chainId, eth_blockNumber, eth_call, eth_getCode, eth_getStorageAt, eth_getLogs]
  deny:  [eth_sendTransaction, eth_sendRawTransaction, eth_sign, eth_signTransaction,
          eth_signTypedData, eth_signTypedData_v3, eth_signTypedData_v4, personal_sign,
          wallet_sendCalls, eth_sendUserOperation]
  default: deny                  # todo lo que no está en allow se rechaza
tools:
  decode_calldata: allow
  simulate_call: allow           # solo lectura y con bloque fijado
  propose_to_tx_service: allow   # como delegado: sin autoridad on-chain
  sign: deny
  execute: deny
payload_rules:
  operation: [0]                 # 0 = CALL; 1 = DELEGATECALL se escala a personas
  safeTxGas: 0                   # con 0, una llamada interna fallida revierte toda la transacción
  baseGas: 0
  gasPrice: 0                    # sin reembolso de gas
  gasToken: "0x0000000000000000000000000000000000000000"
  refundReceiver: "0x0000000000000000000000000000000000000000"
  on_missing_data: stop_and_escalate

En el diseño que proponemos, los límites se aplican fuera del razonamiento del modelo: las herramientas rechazan las solicitudes que exceden el permiso concedido. Si falta un dato necesario para evaluar la operación, el flujo se detiene y pide revisión.

Un paquete de revisión ligado al payload. Lo que firman los owners es un hash EIP-712 de diez campos: to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver y nonce. Desde la versión 1.3.0, el dominio de ese hash incluye el chainId y la dirección del propio Safe. El paquete debe mostrar los diez campos, no solo el destino y el importe, porque varios de ellos cambian el significado de la firma:

  • operation vale 0 para CALL y 1 para DELEGATECALL. Con DELEGATECALL, el código del destino se ejecuta en el contexto del Safe y puede escribir en su almacenamiento, incluida su configuración. En este flujo, cualquier valor distinto de 0 se escala a personas.
  • gasPrice, gasToken y refundReceiver definen un reembolso de gas que paga el Safe. Con gasPrice a 0 no hay reembolso; si refundReceiver es la dirección cero, el reembolso va a tx.origin, es decir, a quien envía la transacción.
  • nonce fija el orden: cada execTransaction que no revierte lo incrementa, aunque haya fallado la llamada interna (posible con safeTxGas o gasPrice distintos de 0), así que unas firmas solo valen para un nonce concreto.

Safe distingue el hash de la transacción del Smart Account, el safeTxHash, del hash de la transacción que finalmente se envía a la red. El paquete debe registrar ambos y mantener su relación con la decisión humana.

Comprobaciones independientes antes de firmar. Proponemos validar con código y herramientas independientes del agente todo lo que pueda comprobarse de forma determinista: red, direcciones, parámetros, nonce y políticas aplicables. La comprobación central es recalcular el safeTxHash fuera de la herramienta que lo propone y compararlo con el que muestra la wallet o el dispositivo de firma. Si la pantalla enseña por separado el hash del dominio y el del mensaje, se comparan los dos.

La firma autoriza el mensaje concreto presentado a la wallet. Si cambia un campo del payload, cambia el hash y se repite la revisión. La aprobación de un borrador anterior no se traslada al siguiente.

Evidencia que conecte preparación y resultado. El registro operativo debe enlazar las fuentes consultadas, el borrador, los resultados de las comprobaciones, la decisión del revisor, las firmas y la ejecución final, con el número de bloque de cada lectura. En el modelo propuesto, el agente puede aportar evidencia, pero no puede modificar la decisión humana ni sustituir los resultados originales de los validadores.

El flujo propuesto, paso a paso

  • Paso 1. El agente, con permisos de lectura y propuesta, reúne el estado del Safe y construye el borrador con su evidencia.
  • Paso 2. Validadores independientes del agente decodifican la llamada, recalculan el safeTxHash y simulan contra un bloque fijado.
  • Paso 3. Si el paquete está incompleto o una comprobación falla, el borrador vuelve al paso 1 o se escala a una persona; nunca avanza con datos que faltan.
  • Paso 4. Si el paquete es válido, los firmantes lo revisan y firman el hash que han comprobado.
  • Paso 5. Una cuenta que no controla el agente envía execTransaction con las firmas reunidas.
  • Paso 6. El equipo verifica el resultado: evento de éxito o de fallo de Safe, efecto en el contrato de destino y coincidencia con lo aprobado.

La firma y la ejecución requieren componentes y permisos externos al agente.

Por qué una política genérica necesita contexto on-chain

Un sistema general de permisos decide si una identidad accede a una herramienta. Para revisar una operación on-chain hace falta, además, saber qué autoriza cada firma y qué rutas pueden ejercer esa autoridad.

En Safe, la ruta ordinaria execTransaction verifica las firmas de los owners conforme al umbral configurado. Esa verificación no depende de quién envía la transacción: con las firmas del umbral, cualquier cuenta puede ejecutarla. Por eso, que el agente no ejecute es una regla operativa, que depende de qué claves y herramientas tiene, o la regla de un guard que compruebe la dirección que envía; no es una propiedad del contrato. Lo que el contrato sí impide es que alguien cambie el payload firmado: cualquier cambio produce otro hash y las firmas dejan de valer.

Safe acepta cuatro tipos de firma: ECDSA, eth_sign, firmas de contrato EIP-1271 y hashes preaprobados con approveHash. Si un owner es a su vez un contrato, por ejemplo otro Safe, su autoridad depende de las reglas de ese contrato, y también hay que revisarla.

Existen además rutas de ejecución mediante módulos que omiten la verificación de firmas. La documentación de Safe advierte de que un módulo puede ejecutar transacciones arbitrarias y de que un módulo malicioso puede tomar el control del Safe. Revisar solo owners y umbral deja incompleto el análisis de autoridad: si un agente puede activar una ruta de módulo, hay que evaluar esa capacidad aunque no figure como owner. Algunos despliegues habilitan un módulo desde el primer día, por ejemplo el módulo de ERC-4337, así que la lista nunca debe darse por vacía.

Los guards añaden comprobaciones antes y después de una transacción, y existen desde la versión 1.3.0. Hasta la 1.4.1, el guard que se configura con setGuard solo revisa execTransaction: las transacciones de módulo no pasan por él. La 1.5.0 añade setModuleGuard para cubrir también la ruta de módulos. Safe advierte de que un guard defectuoso puede bloquear la ejecución, así que hay que verificar qué rutas protege y qué mecanismo de recuperación existe en cada despliegue.

Esta foto de autoridad puede tomarse con cast, de Foundry, contra un bloque fijado. Los slots de almacenamiento son constantes del código de Safe y los hemos contrastado con las versiones 1.4.1 y 1.5.0:

bash
# bash: ejecuta los bloques de este artículo en orden y en la misma sesión
export ETH_RPC_URL=...            # RPC de la red que corresponda
SAFE=0x...                        # dirección del Safe
BLOCK=$(cast block-number)        # fija el bloque para que todas las lecturas sean coherentes

cast call $SAFE "VERSION()(string)" --block $BLOCK
cast call $SAFE "getOwners()(address[])" --block $BLOCK
cast call $SAFE "getThreshold()(uint256)" --block $BLOCK
cast call $SAFE "nonce()(uint256)" --block $BLOCK

# Módulos: lista enlazada que empieza en el centinela 0x...01.
# Si el segundo valor devuelto no es 0x...01, hay más páginas.
cast call $SAFE "getModulesPaginated(address,uint256)(address[],address)" \
  0x0000000000000000000000000000000000000001 50 --block $BLOCK

# Guard de transacciones: slot = keccak256("guard_manager.guard.address")
cast storage $SAFE 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8 --block $BLOCK

# Fallback handler: slot = keccak256("fallback_manager.handler.address")
cast storage $SAFE 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5 --block $BLOCK

# Solo 1.5.0, guard de módulos: slot = keccak256("module_manager.module_guard.address")
cast storage $SAFE 0xb104e0b93118902c651344349b610029d694cfdec91c589c91ebafbcd0289947 --block $BLOCK

Un valor cero en un slot significa que no hay guard o handler configurado, siempre que las llamadas anteriores hayan respondido: en una dirección sin código, o en otra red, todos los slots leen también cero. El fallback handler y DELEGATECALL abren otras vías de autoridad que tratamos en un artículo específico sobre la matriz de permisos. En los Safes anteriores a la versión 1.3.0 no existen los guards, así que un cero en el slot del guard solo indica que la versión no los admite.

La cadena también forma parte del contexto de firma. EIP-712 define campos de dominio como chainId y verifyingContract, y cada protocolo decide cuáles usa. Desde la versión 1.3.0, Safe usa los dos: el chainId y la dirección del Safe, así que el mismo payload firmado para el mismo Safe en otra cadena produce otro hash. Los Safes anteriores dejan el chainId fuera del dominio, así que la misma firma puede valer en otra cadena donde el Safe tenga la misma dirección. El estándar, por sí solo, no protege frente a la reutilización de mensajes firmados; en Safe esa función la cumple el nonce.

Un pago de tesorería preparado por un agente

Consideremos un escenario ilustrativo, no un caso de cliente ni una medición de resultados: un equipo quiere transferir 5.000 unidades de un token ERC-20 desde un Safe con cinco owners y un umbral de tres firmas.

En una transferencia ERC-20 directa, el destino de la llamada es el contrato del token. El destinatario del pago y el importe van dentro de los datos de transfer. El importe se expresa en unidades mínimas, así que hay que leer los decimales del contrato: el estándar ERC-20 los declara opcionales, y con 6 decimales las 5.000 unidades son 5000000000.

bash
TOKEN=0x...                       # contrato del token en esa red, contrastado con una fuente aprobada
RECIPIENT=0x...                   # destinatario aprobado
cast call $TOKEN "decimals()(uint8)" --block $BLOCK
DATA=$(cast calldata "transfer(address,uint256)" $RECIPIENT 5000000000)
cast decode-calldata "transfer(address,uint256)" $DATA   # lo que debe ver el revisor

# safeTxHash según el propio contrato: CALL y sin reembolso de gas
NONCE=$(cast call $SAFE "nonce()(uint256)" --block $BLOCK | cut -d' ' -f1)   # desde 10000, cast añade " [1e4]"
ZERO=0x0000000000000000000000000000000000000000
SAFE_TX_HASH=$(cast call $SAFE \
  "getTransactionHash(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,uint256)(bytes32)" \
  $TOKEN 0 $DATA 0 0 0 0 $ZERO $ZERO $NONCE --block $BLOCK)
echo $SAFE_TX_HASH

Para no depender ni de la interfaz ni del contrato consultado, el hash puede recalcularse fuera de línea con las constantes del código de Safe. Este cálculo coincide con getTransactionHash desde la versión 1.3.0: lo hemos comprobado en Safes 1.3.0 y 1.4.1 y contra el código de la 1.5.0. Las versiones anteriores usan otro dominio, así que conviene leer VERSION antes.

bash
SAFE_TX_TYPEHASH=0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8
DOMAIN_TYPEHASH=0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218
CHAIN_ID=$(cast chain-id)
DOMAIN_HASH=$(cast keccak "$(cast abi-encode "f(bytes32,uint256,address)" $DOMAIN_TYPEHASH $CHAIN_ID $SAFE)")
MESSAGE_HASH=$(cast keccak "$(cast abi-encode \
  "f(bytes32,address,uint256,bytes32,uint8,uint256,uint256,uint256,address,address,uint256)" \
  $SAFE_TX_TYPEHASH $TOKEN 0 "$(cast keccak "$DATA")" 0 0 0 0 $ZERO $ZERO $NONCE)")
RECOMPUTED=$(cast keccak 0x1901${DOMAIN_HASH:2}${MESSAGE_HASH:2})
# debe coincidir con $SAFE_TX_HASH; un valor vacío indica que falló una lectura anterior
[ -n "$SAFE_TX_HASH" ] && [ "$RECOMPUTED" = "$SAFE_TX_HASH" ] && echo "MATCH $RECOMPUTED" || echo "NO MATCH"

La llamada interna se simula como si la enviara el Safe y en el bloque de la foto, con el último comando de esta sección. Esa simulación no ejercita la verificación de firmas ni el guard; para eso hace falta un fork, como se explica más abajo. El paquete de revisión de este pago debe permitir comprobar lo siguiente:

  • Red y Safe: chainId y dirección contrastados con la configuración autorizada, y VERSION, owners, umbral, nonce, módulos, guard y fallback handler leídos en un bloque concreto.
  • Contrato de destino: la dirección del token en esa red, contrastada con una fuente aprobada, y sus decimales.
  • Llamada: transfer decodificada, con el destinatario y el importe en unidades mínimas.
  • Parámetros Safe: operation 0, valor nativo 0, safeTxGas, baseGas y gasPrice a 0, y gasToken y refundReceiver en la dirección cero.
  • Hash: el safeTxHash que devuelve el contrato y el recalculado fuera de línea, idénticos.
  • Simulación: bloque utilizado, resultado de la llamada y variaciones de balance examinadas.
  • Revisión y firma: el payload revisado, el hash que ve cada firmante y su decisión.
bash
# Simulación de la llamada interna, como si la enviara el Safe, en el bloque de la foto
# Algunos tokens, como USDT, no devuelven bool: entonces quita (bool) y comprueba solo que no revierte
cast call $TOKEN "transfer(address,uint256)(bool)" $RECIPIENT 5000000000 --from $SAFE --block $BLOCK

Si las comprobaciones son satisfactorias, las personas aportan las tres firmas requeridas mediante su flujo habitual y una cuenta que no controla el agente envía execTransaction. Después, el equipo comprueba dos cosas distintas: que la transacción se minó y que la llamada interna tuvo éxito. Safe emite ExecutionSuccess o ExecutionFailure con el safeTxHash, y con safeTxGas o gasPrice distintos de cero una llamada interna fallida no revierte la transacción. Una transacción minada no prueba, por sí sola, que el pago se hiciera.

El escenario muestra una separación de responsabilidades. La cantidad del pago y el umbral son supuestos del ejemplo; no demuestran ahorro de tiempo, reducción de incidentes ni rendimiento de una implementación.

Cinco límites del agente en esta arquitectura

En el flujo propuesto, los permisos del agente excluyen estas acciones:

  • Acceder a claves privadas, frases semilla o credenciales de firma.
  • Firmar mensajes o transacciones con autoridad sobre el Safe: ni ECDSA, ni eth_sign, ni approveHash desde una cuenta owner.
  • Ejecutar operaciones del Safe por una ruta de módulo, o enviar execTransaction desde sus propias claves. Lo primero se comprueba en la lista de módulos y, desde la 1.5.0, en el guard de módulos; lo segundo es una regla operativa o de guard, porque el contrato acepta a cualquier remitente.
  • Cambiar owners, umbral, módulos, guards o fallback handler para ampliar su propia autoridad, o proponer un DELEGATECALL que pueda hacerlo.
  • Dar por aprobado un payload modificado o sustituir una decisión humana pendiente.

El equipo debe comprobar estos límites en las herramientas, las credenciales y las rutas accesibles. Las instrucciones del agente orientan su trabajo; la restricción operativa tiene que mantenerse también cuando una salida del modelo es incorrecta. La matriz completa de permisos para agentes con activos digitales, con sus rutas de escalado, es el tema de un artículo específico de esta serie; los fundamentos de permisos para agentes en producción están en «Los agentes IA en producción necesitan permisos, no vibes», enlazado al final.

Cómo introducirlo en un equipo Web3

Empieza por una operación repetida y acotada que ya tenga responsables y un proceso de firma. Para este modelo proponemos cuatro pasos:

  • Mapear la autoridad existente: quién prepara, revisa, firma y ejecuta, y qué módulos, guards, delegados y owners contrato existen. La foto de autoridad con cast es el punto de partida.
  • Definir el paquete de revisión: qué campos, comprobaciones y evidencia deben estar presentes antes de solicitar firmas.
  • Probar la preparación en un entorno controlado. En un fork local con anvil se puede ejecutar la operación completa sin fondos reales, aprobando el hash con cuentas impersonadas mediante approveHash. Ahí conviene introducir errores de red, dirección, decimales, operation o nonce, y comprobar que el flujo los bloquea o los escala.
  • Evaluar el trabajo completo: tiempo de preparación y revisión, borradores rechazados y correspondencia entre el payload aprobado y la operación ejecutada.
bash
# Fork local en el bloque de la foto, en segundo plano: ningún fondo real se mueve
anvil --fork-url $ETH_RPC_URL --fork-block-number $BLOCK --silent &
sleep 5                           # da tiempo a que anvil escuche en el puerto 8545
export ETH_RPC_URL=http://127.0.0.1:8545
OWNERS="0x... 0x... 0x..."        # owners del Safe hasta el umbral (3 en este ejemplo)
EXECUTOR=0x...                    # cualquier cuenta que no sea owner
cast rpc anvil_setBalance $EXECUTOR 0xDE0B6B3A7640000   # 1 ETH de prueba para el gas

# Cada owner aprueba el hash desde una cuenta impersonada.
# Firma de hash preaprobado: r = dirección del owner con ceros a la izquierda hasta 32 bytes, s = 0, v = 1,
# concatenadas por dirección de owner ascendente (Safe rechaza cualquier otro orden).
SIG=0x
for OWNER in $(printf '%s\n' $OWNERS | tr 'A-F' 'a-f' | LC_ALL=C sort); do
  cast rpc anvil_setBalance $OWNER 0xDE0B6B3A7640000
  cast rpc anvil_impersonateAccount $OWNER
  cast send $SAFE "approveHash(bytes32)" $SAFE_TX_HASH --from $OWNER --unlocked
  SIG=${SIG}000000000000000000000000${OWNER:2}000000000000000000000000000000000000000000000000000000000000000001
done

# Cualquier cuenta, también una que no es owner, puede enviar la ejecución
cast rpc anvil_impersonateAccount $EXECUTOR
cast send $SAFE \
  "execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes)" \
  $TOKEN 0 $DATA 0 0 0 0 $ZERO $ZERO $SIG --from $EXECUTOR --unlocked
# Al terminar: kill %1 detiene anvil

La prueba de aceptación debe demostrar también que el agente carece de una ruta accesible para ejercer la autoridad reservada a las personas. Una ejecución que funcionó una vez no permite evaluar ese límite. En el fork, reenviar las mismas firmas desde una cuenta que no es owner debe fallar, porque el nonce ya ha cambiado y, con él, el hash.

Qué sigue necesitando juicio humano

La separación de permisos reduce la autoridad directa del agente, pero sigue siendo necesario revisar la calidad de su propuesta. Una persona puede firmar un payload incorrecto si la información que recibe es incompleta o si no la contrasta.

También hay que gestionar la vigencia de las comprobaciones. Entre la preparación y la ejecución pueden cambiar el nonce, la configuración del Safe o el estado del contrato de destino. Proponemos criterios explícitos para repetir la validación y la simulación cuando esos cambios afecten a la decisión. Una simulación favorable describe las condiciones examinadas, no las futuras.

El flujo añade trabajo de integración y de coordinación de firmantes, y su utilidad debe evaluarse con mediciones del proceso real. Para operaciones repetitivas que necesiten otra política de delegación, corresponde diseñar y revisar por separado la autoridad delegada y sus límites. Si el agente funciona sobre un proveedor de wallets con su propio motor de políticas, la pregunta no desaparece: el proveedor hace cumplir las políticas, pero tu equipo sigue decidiendo qué dicen y tiene que comprobar qué otras rutas llegan al Safe. Un artículo específico de esta serie trata ese caso junto a la matriz de permisos.

Diseñar el límite antes de conectar la tesorería

El primer paso útil es tomar una operación real y dibujar quién puede prepararla, autorizarla y ejecutarla. Después, comprobar que los permisos, la foto de autoridad del Safe y el paquete de revisión reflejan ese reparto. El agente puede preparar el payload, la evidencia y las comprobaciones, pero solo las personas firman el hash EIP-712 que han verificado, y el diseño no deja al agente ninguna clave, herramienta ni ruta de módulo para ejecutarlo.

En Nexuain describimos este método como un concepto de portfolio para operaciones Web3: preparación asistida, aprobación humana y ejecución externa, con artefactos ilustrativos. El trabajo sobre el alcance de las herramientas, las aprobaciones y la trazabilidad de los agentes está en la página de agentes IA con guardrails, aprobaciones y trazabilidad.

Si tu equipo quiere aplicar este enfoque a una operación Safe concreta, el primer entregable es el mapa de autoridad de esa operación, con owners, umbral, módulos, guards, delegados y todas las rutas que pueden llegar a la firma o a la ejecución, y la definición de su paquete de revisión. Puedes solicitar una revisión técnica desde la página de contacto; en el mensaje, menciona este artículo y la operación que tienes en mente, sin claves ni material operativo confidencial.

Fuentes

Documentación consultada el 1 de octubre de 2026. Las fuentes describen mecanismos y arquitecturas; el escenario del pago, la política de ejemplo y los pasos de adopción son propuestas ilustrativas de este artículo. Los bloques de código se han copiado literalmente de este artículo y se han ejecutado de principio a fin con cast y anvil 1.8.3, de Foundry, contra un Safe 1.3.0 y un Safe 1.4.1 en mainnet y en un fork local de cada uno.

Lecturas relacionadas

¿Necesitas aplicar esto a tu lanzamiento o workflow?

Solicita una revisión técnica y mapeamos el primer paso seguro.

Posts relacionados