Saltar al contenido principal

Registrar un Service DID

Esta página explica, paso a paso, cómo dar de alta un Service DID bajo tu DID organizativo. Si todavía no sabes qué es un Service DID, empieza por la introducción.

Resumen del proceso​

Las claves privadas solo se usan en tu equipo, dentro del CLI. La API nunca las ve.

Requisitos previos​

Antes de empezar necesitas:

  1. Un DID organizativo registrado en el entorno donde vas a dar de alta el servicio. Será el DID paraguas. Si aún no lo tienes, sigue el onboarding del DID.
  2. El keystore del DID paraguas (por ejemplo, identity.keystore.json) y su contraseña. Es el fichero que generaste con did-gen keys al crear tu DID.
  3. El CLI isbe-identity-did-gen, versión 3.0.0 o superior. ⬇ Descargar el CLI (ZIP).
  4. Node.js 20 o superior y npm 10 o superior, para ejecutar el CLI.
  5. La URL de la Service DID Registry API del entorno. La tienes en Entornos.
Entorno

En los ejemplos se usa pre-producción (uc-pre). Para producción, usa uc y la URL de producción.

Paso 1 — Instalar el CLI​

Descomprime el ZIP que descargaste en los requisitos previos. Se crea una carpeta isbe-identity-did-gen-3.0.0. Entra en ella e instala el CLI:

cd isbe-identity-did-gen-3.0.0
npm ci
npm run build
npm link

npm link deja disponible el comando did-gen en cualquier carpeta. Comprueba que funciona:

did-gen --version
Si npm link falla con EACCES: permission denied

Es un problema de permisos de la carpeta global de npm, habitual en macOS. El README del CLI explica cómo solucionarlo. También puedes saltarte npm link y ejecutar el CLI desde su carpeta con node dist/index.js en lugar de did-gen.

Paso 2 — Obtener los datos del DID paraguas​

Necesitas dos datos de tu DID paraguas: el DID y su EOA (la dirección de la cuenta que firma tus transacciones). Los obtienes a partir de su keystore:

did-gen did --keystore ./identity.keystore.json --modelDeploy uc-pre

Te pide la contraseña del keystore y muestra:

DID:
did:isbe:uc-pre:z1MsSK9H41YvdCrJPmPycEqijYbk

Public Key:
0x04…

Proof:
0x…

EOA: 0xB8172459924a1e81E511D6473f923E531f7B3a5B

Apunta el DID y la EOA.

Usa el entorno correcto

El --modelDeploy tiene que ser el del entorno donde registraste tu DID: uc-pre en pre-producción. En producción no pongas --modelDeploy (por defecto es uc). Con un entorno equivocado obtendrás un DID distinto, que no es el tuyo.

Paso 3 — Generar la clave del servicio​

Genera un par de claves nuevo para el servicio, en un keystore distinto del de tu DID paraguas:

mkdir -p keys
did-gen keys --out ./keys/facturacion.keystore.json

Elige una contraseña para este keystore. El comando muestra, entre otros datos:

Public Key (hex):
0x04ad5f…(130 caracteres en total)

Apunta la Public Key (hex): es la clave que vas a registrar para el servicio.

No uses la clave del DID paraguas

La clave del servicio tiene que ser distinta de la de tu DID organizativo. Si usas la del paraguas, el alta se rechaza. Puedes reutilizar la clave de otro servicio de tu mismo paraguas, pero nunca la de un DID organizativo ni la de un servicio de otra organización.

Guarda bien facturacion.keystore.json y su contraseña. Es la clave con la que el servicio firmará lo suyo. Para registrar el servicio no la vas a necesitar: el alta la firma el DID paraguas.

Paso 4 — Pedir la transacción de alta​

Abre el Swagger de la Service DID Registry API del entorno (ver Entornos) y busca la operación:

POST /api/v1/contract/registerServiceDid

Cuerpo mínimo​

{
"controllerDid": "did:isbe:uc-pre:z1MsSK9H41YvdCrJPmPycEqijYbk",
"publicKey": "0x04<clave pública del servicio>",
"publicKeyType": "secp256k1",
"label": "facturacion",
"expiresAt": 0,
"from": "0xB8172459924a1e81E511D6473f923E531f7B3a5B"
}
CampoQué poner
controllerDidEl DID paraguas del paso 2.
publicKeyLa clave pública del servicio del paso 3. Empieza por 0x04.
publicKeyTypesecp256k1.
labelUn nombre corto para que tú identifiques el servicio, por ejemplo facturacion. En la cadena se guarda solo su huella (hash), no el texto.
expiresAtFecha de caducidad en segundos Unix. 0 significa que no caduca.
fromLa EOA del DID paraguas del paso 2.

Cuerpo completo, con campos libres​

Cualquier campo que añadas además de los anteriores se guarda en la cadena y aparece en el DID Document del servicio (ver Campos libres). Por ejemplo:

{
"controllerDid": "did:isbe:uc-pre:z1MsSK9H41YvdCrJPmPycEqijYbk",
"publicKey": "0x04<clave pública del servicio>",
"publicKeyType": "secp256k1",
"label": "facturacion-electronica",
"expiresAt": 0,
"from": "0xB8172459924a1e81E511D6473f923E531f7B3a5B",

"name": "Servicio de Facturación Electrónica",
"description": "Emisión y recepción de facturas electrónicas (Facturae y UBL) para clientes empresariales.",
"serviceType": "InvoicingService",
"version": "2.1.0",
"tags": ["facturacion", "facturae", "ubl", "b2b"],
"alsoKnownAs": ["https://facturacion.ejemplo.es"],
"organization": {
"legalName": "Ejemplo Soluciones S.A.",
"taxId": "A12345678",
"country": "ES",
"website": "https://www.ejemplo.es"
},
"contact": {
"email": "soporte.facturacion@ejemplo.es"
},
"service": [
{
"id": "#api",
"type": "InvoicingAPI",
"serviceEndpoint": "https://api.facturacion.ejemplo.es/v2"
},
{
"id": "#openapi",
"type": "OpenAPISpecification",
"serviceEndpoint": "https://api.facturacion.ejemplo.es/v2/openapi.json"
},
{
"id": "#vc-issuer",
"type": "CredentialIssuer",
"serviceEndpoint": "https://facturacion.ejemplo.es/.well-known/openid-credential-issuer"
}
],
"termsOfService": "https://www.ejemplo.es/legal/condiciones-facturacion"
}

Los id de service (#api, #openapi…) son relativos al propio Service DID: #api equivale a did:isbe:svc:…:3#api.

Respuesta​

La API devuelve la transacción sin firmar:

{
"to": "0x00000000000000000000000000000000000015Be",
"data": "0x2cc72092…",
"gasLimit": "0x65bc8",
"gasPrice": "0xfa0",
"chainId": "0x…",
"nonce": "0x1",
"value": "0x0",
"from": "0xB8172459924a1e81E511D6473f923E531f7B3a5B"
}

Copia la respuesta entera y guárdala en un fichero unsigned-tx.json, en la carpeta desde la que vas a ejecutar el CLI.

Paso 5 — Firmar la transacción​

La transacción la firma el DID paraguas, con su keystore:

did-gen sign-tx --keystore ./identity.keystore.json --tx-file unsigned-tx.json > signed.hex

Te pide la contraseña del keystore del paraguas. Antes de firmar, el CLI comprueba que la transacción es de tu cuenta: si el from no coincide con tu keystore, no la firma.

La transacción firmada queda en signed.hex. Para copiarla sin errores, cópiala desde el fichero en vez de seleccionarla en el terminal:

cat signed.hex | pbcopy

pbcopy es de macOS. En Linux puedes usar xclip -selection clipboard < signed.hex, o abrir el fichero y copiar su contenido.

Copia la firma entera

Si se pierde un solo carácter al copiarla, la API responde invalid BytesLike value y la transacción no se envía. Copiarla desde signed.hex lo evita.

Paso 6 — Enviar la transacción​

En el Swagger, busca:

POST /api/v1/transactions/send

Y envía:

{
"signedRawTransaction": "0x01f9…"
}

La respuesta incluye el hash de la transacción (tx_hash) y su recibo (receipt):

  • 200: la transacción se ha procesado. Si receipt.status es 1, el Service DID está registrado.
  • 206: la transacción se ha enviado, pero el recibo aún no estaba listo. Espera unos segundos y compruébalo en el paso 7.

Paso 7 — Comprobar el Service DID​

Encontrar el identificador​

Lista los Service DIDs de tu paraguas:

GET /api/v1/service-dids?controller=<DID paraguas>

Si usas curl, codifica el DID en la URL (los : pasan a ser %3A):

curl -s "<API>/api/v1/service-dids?controller=did%3Aisbe%3Auc-pre%3Az1MsSK9H41YvdCrJPmPycEqijYbk"

El servicio nuevo es el que tiene el nonce más alto. Su identificador está en serviceDid:

{
"items": [
{
"serviceDid": "did:isbe:svc:uc-pre:z1MsSK9H41YvdCrJPmPycEqijYbk:3",
"controllerDid": "did:isbe:uc-pre:z1MsSK9H41YvdCrJPmPycEqijYbk",
"signingKeyAddress": "0x…",
"nonce": "3",
"deactivated": false,
…
}
],
"total": "3",
…
}

Resolver el DID Document​

GET /api/v1/identifiers/did:isbe:svc:uc-pre:z1MsSK9H41YvdCrJPmPycEqijYbk:3

Comprueba que:

  • controller es tu DID paraguas.
  • verificationMethod contiene la clave del servicio.
  • Aparecen tus campos libres, si los añadiste.
  • No aparece "deactivated": true.

Errores frecuentes​

ErrorCausaSolución
403 FORBIDDEN — 'from' is not an active controller of 'controllerDid'La cuenta from no controla el DID paraguas.Usa la EOA del DID paraguas (paso 2).
400 — 'controllerDid' is not validEl DID paraguas está mal escrito o es de otro entorno (por ejemplo, un uc-dev en pre-producción).Revisa el DID y el --modelDeploy del paso 2.
400 — The service document cannot set …Has usado un campo reservado en los campos libres.Quita o renombra ese campo (ver Campos libres).
400 — The service document is … bytes; the registry accepts at most 4096.Los campos libres superan los 4096 bytes.Reduce los campos libres.
400 — request/body must have required property …Falta algún campo obligatorio o tiene un formato incorrecto.Revisa el cuerpo con la tabla del paso 4.
500 — invalid BytesLike valueLa transacción firmada está incompleta: se perdió algún carácter al copiarla.Cópiala de nuevo desde signed.hex.
500 — transaction execution revertedEl contrato ha rechazado el alta. Lo más habitual: la clave del servicio es la del DID paraguas o la de un servicio de otra organización.Genera una clave nueva para el servicio (paso 3) y repite desde el paso 4.
500 — Known transactionEsa transacción ya se había enviado.Comprueba en el paso 7 si el servicio ya está registrado.
500 — nonce too lowLa transacción se pidió antes de que se procesara otra anterior de la misma cuenta.Pide una transacción nueva (paso 4) y fírmala otra vez.

Siguientes pasos​