diff --git a/apps/web/src/content/blog.ts b/apps/web/src/content/blog.ts index 53ed140..1b09e49 100644 --- a/apps/web/src/content/blog.ts +++ b/apps/web/src/content/blog.ts @@ -21,6 +21,198 @@ export interface BlogPost { } export const BLOG_POSTS: BlogPost[] = [ + { + slug: "0xgasless-paymaster-pilot-kya", + date: "2026-10-08", + author: { + name: "Giovanny Amador", + role: { en: "Co-founder, Engineering Lead", es: "Co-founder, Líder de Ingeniería" }, + }, + readMinutes: 6, + category: "PILOT", + title: { + en: "How a Paymaster Decides Who Gets Free Gas: Our Testnet Pilot With 0xgasless", + es: "Cómo un Paymaster Decide a Quién Patrocinarle el Gas: Nuestro Piloto en Testnet con 0xgasless", + }, + excerpt: { + en: "A paymaster that sponsors gas for any wallet drains fast. In a technical pilot on Fuji testnet, 0xgasless's sponsorship service checked KUMPLY's verify() before approving gas: a control wallet was refused without an attestation, then sponsored after one was issued. Three transactions you can check, one ERC-7562 detail that breaks on-chain versions of the check, and an honest status: testnet, demo attestations, no mainnet use.", + es: "Un paymaster que patrocina el gas de cualquier wallet se vacía rápido. En un piloto técnico en testnet Fuji, el servicio de patrocinio de 0xgasless consultó el verify() de KUMPLY antes de aprobar el gas: una wallet de control fue rechazada sin attestation y luego patrocinada después de que se le emitió una. Tres transacciones que puedes revisar, un detalle de ERC-7562 que rompe las versiones on-chain de la revisión, y un estado honesto: testnet, attestations de demo, sin uso en mainnet.", + }, + bodyHtml: { + en: ` +

A paymaster pays the gas fee for someone else's transaction. That is the appeal of ERC-4337 for onboarding: a new user or an AI agent can act without first holding the chain's native token. It is also an open invitation. A paymaster that sponsors every wallet that asks gets scripted wallets, and its deposit drains as fast as someone can write a loop.

+ +

We ran a technical pilot on Avalanche Fuji testnet with 0xGasless, which runs ERC-4337 account-abstraction infrastructure (bundler, paymaster, smart accounts) and x402 payment rails on Avalanche, and showed it live on September 30, 2026. It tests one answer to "who do we sponsor?": the accounts that hold a valid KUMPLY attestation, and nobody else. This post covers what ran, three transactions you can check yourself, one ERC-7562 detail that trips up on-chain versions of this check, and what the pilot does not prove.

+ +

The problem: free gas attracts everything

+ +

Gating sponsorship needs a signal with three properties. It has to be cheap to check on every request. It has to expire or be revocable, so a bad actor does not keep access forever. And it has to attach to the address that actually sends the UserOperation, which in ERC-4337 is the smart account (userOp.sender), not the EOA that controls it. An allowlist maintained by hand covers none of that at scale. An attestation read from a public contract covers all three.

+ +

How the pilot is wired

+ +

0xgasless runs a sponsorship service in front of its paymaster. For UserOperations submitted under the pilot's API key on Fuji, the service calls KUMPLY's verify() for the smart account and approves sponsorship only when the account holds a valid attestation. Which tier it requires is their policy to set. The approval travels with the UserOperation as paymaster data, and on-chain their paymaster contract checks that the approval is genuine before the EntryPoint runs the operation.

+ +

One point worth being exact about: that on-chain paymaster does not read KUMPLY. It is a VerifyingSingletonPaymaster (source verified on Routescan), and its bytecode contains neither our AttestationStore address nor the selectors for verify() or attestations(). The KUMPLY check happens in the service. The chain only confirms the service's approval.

+ +
+ + +STEP 1 +UserOperation +from a smart account +asks for sponsored gas + +STEP 2 +0xgasless service +reads KUMPLY verify() +signs approval if valid + +STEP 3 +On-chain, Fuji +EntryPoint + paymaster +check approval, run op + +KUMPLY AttestationStore +verify(sender), free read + + + +No valid attestation: +refused, no gas spent +Only step 3 is a +transaction + + + + + + +
+ +

The demo, in three transactions

+ +

During the live demo, 0xgasless's service refused to sponsor a control wallet that had no attestation. We then issued a Tier 5 attestation to it, and the same wallet was sponsored. The refusal happened inside their service, so it has no transaction. What the chain does show is that the control account had no attestation at block 58,898,378, one block before we issued it. The three moments that did land on-chain are all on Fuji, and you can check each one. All times are UTC, September 30, 2026.

+ +
+

1. Sponsored operation, original pilot wallet. Block 58,898,127, 15:05:58. A UserOperation from the smart account that already held a demo Tier 5 attestation (issued on September 25), paid for by the paymaster: 0xc3b40a...2b70. Status success. The paymaster paid 0.000191 AVAX in test gas.

+

2. Attestation issued to the control wallet. Block 58,898,379, 15:14:04. One AttestationIssued event, with the control account 0x91a0...Bf33 as the subject, Tier 5, expiry September 30, 2027: 0x084e7d...d8aa. Status success. Issued by KUMPLY's verifier key, on our side.

+

3. Sponsored operation, control wallet. Block 58,898,490, 15:17:38. The same account, now sponsored: 0x4a4490...d9b1. Status success. The paymaster paid 0.000480 AVAX in test gas.

+
+ +

One detail in transaction 3 is easy to miss. The control account did not exist yet. That UserOperation carried initCode, and the logs include an AccountDeployed event, so the account was deployed by the very operation that was sponsored. We had issued the attestation to an address that was still counterfactual, and it worked because the attestation is keyed by address, not by whether code lives there yet. It also shows why the check has to run on userOp.sender: that is the address that exists in the UserOperation before anything is deployed.

+ +

The ERC-7562 catch: verify() can't run inside validation

+ +

The pilot checks KUMPLY off-chain, so it never hit this. A team that wants the check inside its own paymaster will. ERC-7562 defines the validation rules bundlers enforce on UserOperations, and rule OP-011 blocks a list of opcodes during validation, including TIMESTAMP. KUMPLY's verify() compares the expiry with block.timestamp, which is exactly that opcode. Call it from validatePaymasterUserOp and a bundler that enforces ERC-7562 will reject the operation.

+ +

The fix is to read the raw record instead. attestations(sender) returns the stored fields without comparing time, and the paymaster hands the expiry to the EntryPoint as validUntil in the returned validationData. The EntryPoint enforces that time check itself, outside validation. In our example, kumplyValidationData(sender) returns the rejection value when there is no attestation, when it was revoked, or when the tier is not exactly the required one, and otherwise packs the expiry into validUntil. The tier match is exact on purpose: tiers 1 to 3 are a ladder for people, while 4 (business) and 5 (agent) are separate categories.

+ +

The example is KumplyPaymasterCheck.sol, with 10 Hardhat tests that pass today. They cover a never-attested account, a person tier, a business, revocation, an expired record, a re-issue, and a trace check that the function never executes TIMESTAMP, unlike verify(). It is example code, not audited, and the pilot does not use it. The integration notes live at kumply.xyz/developers#paymasters.

+ +

Where this stands

+ +

This is a technical pilot on testnet. The attestations in it are demo attestations: KUMPLY's team issued them directly on Fuji, and there is no identity verification behind them. No document check, no business check, no review of the agent. On-chain, a pilot Tier 5 only records that KUMPLY marked that address as Tier 5 until an expiry. Please don't read it as proof of who operates an agent. Nothing from this pilot touches Mainnet C-Chain, and as of October 8, 2026, the mainnet AttestationStore reports zero attestations issued.

+ +

On October 2, 0xgasless said publicly on X: "Excited to support teams like @KumplyAvax with 0xgasless infrastructure, sponsored transactions and agentic payment rails." We appreciate it. Mainnet is something we expect to discuss with them next, but nothing is scheduled. Before any attestation is issued there, we plan to move our issuing keys to stronger custody and to run identity checks through a production provider.

+ +

If you want to build something similar

+ +

Gate on the account that sends the UserOperation, not its owner. Decide whether your check lives off-chain, like the pilot, or on-chain, and if it is on-chain, read attestations(sender) and return the expiry as validUntil. Match the tier exactly instead of using a "greater than or equal" comparison. Keep any approval you sign short-lived and never longer than the attestation's expiry, so a revocation takes effect quickly. Then start on Fuji, where reading verify() is free.

+ +

The guide is at kumply.xyz/developers, and the TypeScript SDK is on npm as @kumply/sdk (version 1.3.0 at the time of writing).

+ +

This post was drafted with AI assistance (Claude) under our direction and reviewed by hand. Every transaction, block, and quote was checked against Fuji and the sources below on October 8, 2026. More on how we use AI: docs/AI-USAGE.md.

+ +

Sources: ERC-7562, 0xgasless on X, October 2, 2026, sponsored operation, original wallet, attestation to the control wallet, sponsored operation, control wallet.

+`, + es: ` +

Un paymaster paga la comisión de gas de la transacción de alguien más. Ese es el atractivo de ERC-4337 para el onboarding: un usuario nuevo o un agente de IA puede actuar sin tener antes el token nativo de la cadena. También es una invitación abierta. Un paymaster que patrocina a toda wallet que lo pide recibe wallets generadas con scripts, y su depósito se vacía tan rápido como alguien escriba un ciclo.

+ +

Corrimos un piloto técnico en la testnet Fuji de Avalanche con 0xGasless, que opera infraestructura de abstracción de cuentas ERC-4337 (bundler, paymaster, smart accounts) y rieles de pago x402 en Avalanche, y lo mostramos en vivo el 30 de septiembre de 2026. Prueba una respuesta a "¿a quién patrocinamos?": a las cuentas que tienen una attestation válida de KUMPLY, y a nadie más. Este post cubre qué corrió, tres transacciones que puedes revisar tú mismo, un detalle de ERC-7562 que rompe las versiones on-chain de esta revisión, y lo que el piloto no demuestra.

+ +

El problema: el gas gratis atrae de todo

+ +

Para controlar el patrocinio hace falta una señal con tres propiedades. Tiene que ser barata de revisar en cada solicitud. Tiene que expirar o poder revocarse, para que un mal actor no conserve el acceso para siempre. Y tiene que ligarse a la dirección que de verdad envía la UserOperation, que en ERC-4337 es la smart account (userOp.sender), no la EOA que la controla. Una lista de permitidos mantenida a mano no cubre nada de eso a escala. Una attestation leída de un contrato público cubre las tres.

+ +

Cómo está conectado el piloto

+ +

0xgasless corre un servicio de patrocinio frente a su paymaster. Para las UserOperations enviadas bajo la API key del piloto en Fuji, el servicio llama al verify() de KUMPLY para la smart account y aprueba el patrocinio solo cuando la cuenta tiene una attestation válida. Qué tier exige es política suya. La aprobación viaja con la UserOperation como datos del paymaster, y on-chain su contrato paymaster revisa que la aprobación sea genuina antes de que el EntryPoint ejecute la operación.

+ +

Un punto en el que conviene ser exactos: ese paymaster on-chain no lee KUMPLY. Es un VerifyingSingletonPaymaster (código verificado en Routescan), y su bytecode no contiene ni la dirección de nuestro AttestationStore ni los selectores de verify() o attestations(). La revisión de KUMPLY ocurre en el servicio. La cadena solo confirma la aprobación del servicio.

+ +
+ + +PASO 1 +UserOperation +de una smart account +pide gas patrocinado + +PASO 2 +Servicio 0xgasless +lee verify() de KUMPLY +firma si es válida + +PASO 3 +On-chain, Fuji +EntryPoint + paymaster +revisan y ejecutan + +KUMPLY AttestationStore +verify(sender), lectura gratis + + + +Sin attestation válida: +rechazo, sin gastar gas +Solo el paso 3 es +una transacción + + + + + + +
+ +

La demo, en tres transacciones

+ +

Durante la demo en vivo, el servicio de 0xgasless se negó a patrocinar una wallet de control que no tenía attestation. Después le emitimos una attestation Tier 5, y esa misma wallet fue patrocinada. El rechazo ocurrió dentro de su servicio, así que no tiene transacción. Lo que la cadena sí muestra es que la cuenta de control no tenía attestation en el bloque 58,898,378, un bloque antes de que la emitiéramos. Los tres momentos que sí quedaron on-chain están en Fuji y puedes revisar cada uno. Todas las horas son UTC, 30 de septiembre de 2026.

+ +
+

1. Operación patrocinada, wallet original del piloto. Bloque 58,898,127, 15:05:58. Una UserOperation de la smart account que ya tenía una attestation Tier 5 de demo (emitida el 25 de septiembre), pagada por el paymaster: 0xc3b40a...2b70. Estado: success. El paymaster pagó 0.000191 AVAX de gas de prueba.

+

2. Attestation emitida a la wallet de control. Bloque 58,898,379, 15:14:04. Un evento AttestationIssued, con la cuenta de control 0x91a0...Bf33 como sujeto, Tier 5, vencimiento el 30 de septiembre de 2027: 0x084e7d...d8aa. Estado: success. La emitió la llave de verificador de KUMPLY, de nuestro lado.

+

3. Operación patrocinada, wallet de control. Bloque 58,898,490, 15:17:38. La misma cuenta, ahora patrocinada: 0x4a4490...d9b1. Estado: success. El paymaster pagó 0.000480 AVAX de gas de prueba.

+
+ +

Hay un detalle en la transacción 3 que es fácil pasar por alto. La cuenta de control todavía no existía. Esa UserOperation traía initCode y los logs incluyen un evento AccountDeployed, así que la cuenta se desplegó con la misma operación que fue patrocinada. Le habíamos emitido la attestation a una dirección que todavía era contrafactual, y funcionó porque la attestation está ligada a la dirección, no a que ya haya código ahí. También muestra por qué la revisión debe hacerse sobre userOp.sender: es la dirección que existe en la UserOperation antes de que se despliegue nada.

+ +

El detalle de ERC-7562: verify() no puede correr dentro de la validación

+ +

El piloto revisa KUMPLY off-chain, así que nunca se topó con esto. Un equipo que quiera la revisión dentro de su propio paymaster, sí. ERC-7562 define las reglas de validación que aplican los bundlers a las UserOperations, y la regla OP-011 bloquea una lista de opcodes durante la validación, entre ellos TIMESTAMP. El verify() de KUMPLY compara el vencimiento con block.timestamp, que es justo ese opcode. Si lo llamas desde validatePaymasterUserOp, un bundler que aplique ERC-7562 rechazará la operación.

+ +

La solución es leer el registro crudo. attestations(sender) devuelve los campos guardados sin comparar el tiempo, y el paymaster le entrega el vencimiento al EntryPoint como validUntil dentro del validationData que regresa. El EntryPoint aplica esa revisión de tiempo por su cuenta, fuera de la validación. En nuestro ejemplo, kumplyValidationData(sender) devuelve el valor de rechazo cuando no hay attestation, cuando fue revocada o cuando el tier no es exactamente el requerido, y en cualquier otro caso empaca el vencimiento en validUntil. El tier se compara de forma exacta a propósito: los tiers 1 a 3 son una escalera para personas, mientras que el 4 (empresa) y el 5 (agente) son categorías separadas.

+ +

El ejemplo es KumplyPaymasterCheck.sol, con 10 pruebas de Hardhat que hoy pasan. Cubren una cuenta nunca atestada, un tier de persona, una empresa, la revocación, un registro vencido, una re-emisión, y una prueba de traza de que la función nunca ejecuta TIMESTAMP, a diferencia de verify(). Es código de ejemplo, sin auditar, y el piloto no lo usa. Las notas de integración están en kumply.xyz/developers#paymasters.

+ +

En qué punto está esto

+ +

Es un piloto técnico en testnet. Las attestations son de demo: el equipo de KUMPLY las emitió directamente en Fuji, y no hay verificación de identidad detrás. No hay revisión de documentos, ni de la empresa, ni del agente. On-chain, un Tier 5 del piloto solo registra que KUMPLY marcó esa dirección como Tier 5 hasta un vencimiento. Por favor no lo tomes como prueba de quién opera un agente. Nada de este piloto toca Mainnet C-Chain, y al 8 de octubre de 2026 el AttestationStore de mainnet reporta cero attestations emitidas.

+ +

El 2 de octubre, 0xgasless dijo públicamente en X: "Excited to support teams like @KumplyAvax with 0xgasless infrastructure, sponsored transactions and agentic payment rails." Lo agradecemos. Mainnet es algo que esperamos platicar con ellos más adelante, pero no hay nada agendado. Antes de emitir cualquier attestation ahí, planeamos mover nuestras llaves de emisión a una custodia más fuerte y hacer las verificaciones de identidad con un proveedor en producción.

+ +

Si quieres construir algo parecido

+ +

Controla con la cuenta que envía la UserOperation, no con su dueño. Decide si tu revisión vive off-chain, como en el piloto, u on-chain, y si es on-chain, lee attestations(sender) y devuelve el vencimiento como validUntil. Compara el tier de forma exacta en vez de usar un "mayor o igual". Mantén cualquier aprobación que firmes de corta duración y nunca más larga que el vencimiento de la attestation, para que una revocación surta efecto rápido. Y empieza en Fuji, donde leer verify() es gratis.

+ +

La guía está en kumply.xyz/developers, y el SDK de TypeScript está en npm como @kumply/sdk (versión 1.3.0 al momento de escribir esto).

+ +

Este post se redactó con asistencia de IA (Claude) bajo nuestra dirección y se revisó a mano. Cada transacción, bloque y cita se verificó contra Fuji y las fuentes de abajo el 8 de octubre de 2026. Más sobre cómo usamos la IA: docs/AI-USAGE.md.

+ +

Fuentes: ERC-7562, 0xgasless en X, 2 de octubre de 2026, operación patrocinada, wallet original, attestation a la wallet de control, operación patrocinada, wallet de control.

+`, + }, + }, { slug: "kya-workshop-behind-the-scenes-live-bugs", date: "2026-09-27",