Saltar al contenido principal

Recuperación

información

Esta guía está disponible en tres lenguajes de programación diferentes: Typescript, Kotlin y Flutter (Dart). Puedes cambiar la versión mostrada en cada página mediante los botones de arriba.

El estándar Sep-30 define la forma estándar para que un individuo (por ejemplo, un usuario o una billetera) recupere el acceso a su cuenta Stellar después de perder su clave privada sin proporcionar ningún control de terceros sobre la cuenta. Durante este flujo, la billetera se comunica con uno o más servidores de firma de recuperación para registrar la billetera para una posible recuperación posterior si es necesario.

Crear Cuenta Recuperable

Primero, vamos a crear una clave de cuenta, una clave de dispositivo y una clave de recuperación que estarán asociadas a la cuenta.

const accountKp = wallet.stellar().account().createKeypair();
const deviceKp = wallet.stellar().account().createKeypair();
const recoveryKp = wallet.stellar().account().createKeypair();

El accountKp es la cuenta principal de la billetera. El deviceKp lo agregaremos a la billetera como firmante para que un dispositivo (por ejemplo, un dispositivo móvil que alberga una billetera) pueda tomar control de la cuenta. Y el recoveryKp se usará para identificar la clave con los servidores de recuperación.

A continuación, identifiquemos los servidores de recuperación y creemos nuestro objeto de recuperación:

const server1Key = "server1";
const server1 = {
endpoint: "recovery-example.com",
authEndpoint: "auth-example.com",
homeDomain: "test-domain",
};

const server2Key = "server2";
const server2 = {
endpoint: "recovery-example2.com",
authEndpoint: "auth-example2.com",
homeDomain: "test-domain2",
};

const recovery = wallet.recovery({
servers: { [server1Key]: server1, [server2Key]: server2 },
});

A continuación, necesitamos definir identidades SEP-30. En este ejemplo, vamos a crear una identidad para ambos servidores. Registrar una identidad le indica al servidor de recuperación qué identidades están autorizadas a acceder a la cuenta.

const identity1 = {
role: RecoveryRole.OWNER,
authMethods: [
{
type: RecoveryType.STELLAR_ADDRESS,
value: recoveryKp.publicKey,
},
],
};

const identity2 = {
role: RecoveryRole.OWNER,
authMethods: [
{
type: RecoveryType.EMAIL,
value: "[email protected]",
},
],
};

Aquí, la clave de Stellar y el correo electrónico se utilizan como métodos de recuperación. Otros servidores de recuperación pueden admitir el teléfono como método de recuperación también.

Puedes leer más sobre las identidades SEP-30 aquí

A continuación, vamos a crear una cuenta recuperable:

const config = {
accountAddress: accountKp,
deviceAddress: deviceKp,
accountThreshold: { low: 10, medium: 10, high: 10 },
accountIdentity: { [server1Key]: [identity1], [server2Key]: [identity2] },
signerWeight: { device: 10, recoveryServer: 5 },
};
const recoverableWallet = await recovery.createRecoverableWallet(config);

Con los parámetros dados, esta función creará una transacción que:

  1. Establezca deviceKp como la clave principal de la cuenta. Ten en cuenta que la clave maestra perteneciente a accountKp estará bloqueada. deviceKp debe ser utilizado como firmante principal.
  2. Establecer todos los umbrales de operación a 10. Puedes leer más sobre el umbral en la documentación
  3. Usa identidades que se definieron anteriormente en ambos servidores. (Eso significa que ambos servidores aceptarán la autenticación SEP-10 a través de recoveryKp como método de autenticación)
  4. Establecer el peso de la clave del dispositivo a 10 y el peso del servidor de recuperación a 5. Dados estos umbrales de cuenta, ambos servidores deben ser utilizados para recuperar la cuenta, ya que la transacción firmada por uno solo tendrá un peso de 5, lo cual no es suficiente para cambiar la clave de cuenta.

Finalmente, firma y envía la transacción a la red:

recoverableWallet.transaction.sign(accountKp.keypair);

await stellar.submitTransaction(recoverableWallet.transaction);

Obtener Información de Cuenta

Puedes obtener información de la cuenta de uno o más servidores. Para hacerlo, primero necesitamos autenticarnos con un servidor de recuperación usando el método de autenticación SEP-10:

const authToken = await recovery
.sep10Auth(server1Key)
.authenticate({ accountKp: recoveryKp });

A continuación, obtén información de la cuenta usando tokens de autenticación:

const accountResp = await recovery.getAccountInfo(accountKp, {
[server1Key]: authToken,
});

Nuestra segunda identidad utiliza un correo electrónico como método de autenticación. Para eso no podemos usar un token de autenticación [SEP-10] para ese servidor. En su lugar, necesitamos usar un token que vincule el correo electrónico con el usuario. Por ejemplo, los tokens de Firebase son un buen caso de uso para esto. Para usar esto, el servidor de firma de recuperación necesita estar preparado para manejar este tipo de tokens.

Obtener información de la cuenta usando estos tokens es lo mismo que antes.

// get token from firebase
const firebaseToken = AuthToken.from(<firebase token string>)

const accountResp = await recovery.getAccountInfo(accountKp, {
[server2Key]: firebaseToken,
});

Recuperar Billetera

Supongamos que hemos perdido nuestra clave de dispositivo y necesitamos recuperar nuestra billetera.

Primero, necesitamos autenticarnos con ambos servidores de recuperación:

const authToken1 = await recovery
.sep10Auth(server1Key)
.authenticate({ accountKp: recoveryKp });

// get firebase token using firebase
const firebaseToken = AuthToken.from(<firebase token string>)

Necesitamos saber las direcciones de firma de recuperación que se utilizarán para firmar la transacción. Puedes obtenerlas del objeto de billetera recuperable que creamos anteriormente (recoverableWallet.signers), o consultando la información de la cuenta de los servidores de recuperación.

const recoverySignerAddress1 = recoverableWallet.signers[0];
const recoverySignerAddress2 = recoverableWallet.signers[1];

A continuación, crea una nueva clave de dispositivo y recupera una transacción firmada que reemplace la clave de dispositivo:

const newDeviceKp = accountService.createKeypair();

const serverAuth = {
[server1Key]: {
signerAddress: recoverySignerAddress1,
authToken1,
},
[server2Key]: {
signerAddress: recoverySignerAddress2,
firebaseToken,
},
};

const recoverTxn = await recovery.replaceDeviceKey(
accountKp,
newDeviceKp,
serverAuth,
);

Llamar a esta función creará una transacción que bloquea la clave de dispositivo anterior y la reemplaza con tu nueva clave (teniendo el mismo peso que la antigua). Ambos firmantes de recuperación habrán firmado la transacción.

La clave de dispositivo perdida se deduce automáticamente si no se proporciona. Un firmante se considerará una clave de dispositivo si se cumple una de estas condiciones:

  1. Es el único firmante que no está en serverAuth.
  2. Todos los firmantes en serverAuth tienen el mismo peso y el firmante potencial es el único con un peso diferente.

Ten en cuenta que la cuenta creada anteriormente coincidirá con el primer criterio. Si se utilizara un esquema 2-3, entonces se cumpliría el segundo criterio. (En el esquema 2-3, se utilizan 3 servidores y 2 de ellos son suficientes para recuperar la clave. Este es un enfoque recomendado.)

Nota: también puedes usar funciones más de bajo nivel signWithRecoveryServers para firmar transacciones arbitrarias.

Finalmente, es hora de enviar la transacción:

await stellar.submitTransaction(recoverTxn);