Recuperación
Esta guía está disponible en cuatro lenguajes de programación diferentes: Typescript, Kotlin, Flutter (Dart) y Swift. 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.
- TypeScript
const accountKp = wallet.stellar().account().createKeypair();
const deviceKp = wallet.stellar().account().createKeypair();
const recoveryKp = wallet.stellar().account().createKeypair();
La accountKp
es la cuenta principal de la billetera. El deviceKp
que vamos a agregar a la billetera como un firmante para que un dispositivo (por ejemplo, un dispositivo móvil en el que se aloja la billetera) pueda tomar control de la cuenta. Y el recoveryKp
se utilizará 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:
- TypeScript
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 dice al servidor de recuperación qué identidades están autorizadas para acceder a la cuenta.
- TypeScript
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 soportar el teléfono como método de recuperación también.
Puedes leer más sobre identidades SEP-30 aquí
A continuación, creemos una cuenta recuperable:
- TypeScript
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 hará:
- Establecer
deviceKp
como la clave de cuenta principal. Ten en cuenta que la clave maestra perteneciente aaccountKp
estará bloqueada.deviceKp
debe usarse como un firmante principal en su lugar. - Establecer todos los umbrales de operación en 10. Puedes leer más sobre el umbral en la documentación
- Usar identidades que se definieron antes en ambos servidores. (Eso significa, que ambos servidores aceptarán la autenticación SEP-10 a través de
recoveryKp
como un método de autenticación) - Establecer el peso de clave del dispositivo en 10, y el peso del servidor de recuperación en 5. Dado estos umbrales de cuenta, ambos servidores deben ser usados para recuperar la cuenta, ya que una transacción firmada por uno solo tendrá un peso de 5, el cual no es suficiente para cambiar la clave de la cuenta.
Finalmente, firma y envía la transacción a la red:
- TypeScript
recoverableWallet.transaction.sign(accountKp.keypair);
await stellar.submitTransaction(recoverableWallet.transaction);
Obtener Información de la Cuenta
Puedes obtener información de la cuenta desde uno o más servidores. Para hacerlo, primero necesitamos autenticar con un servidor de recuperación usando el método de autenticación SEP-10:
- TypeScript
const authToken = await recovery
.sep10Auth(server1Key)
.authenticate({ accountKp: recoveryKp });
A continuación, obtiene información de la cuenta utilizando los tokens de autenticación:
- TypeScript
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 cambio, necesitamos usar un token que vincule el correo electrónico al usuario. Por ejemplo, los tokens de Firebase son un buen caso de uso para esto. Para usar esto, el servidor de firmante 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.
- TypeScript
// 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 autenticar con ambos servidores de recuperación:
- TypeScript
const authToken1 = await recovery
.sep10Auth(server1Key)
.authenticate({ accountKp: recoveryKp });
// get firebase token using firebase
const firebaseToken = AuthToken.from(<firebase token string>)
Necesitamos conocer las direcciones de los firmantes de recuperación que se utilizarán para firmar la transacción. Puedes obtenerlas de la billetera recuperable que creamos antes (recoverableWallet.signers
), o mediante la obtención de información de la cuenta desde los servidores de recuperación.
- TypeScript
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:
- TypeScript
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 será considerado una clave de dispositivo, si una de estas condiciones coincide:
- Es el único firmante que no está en
serverAuth
. - Todos los firmantes en
serverAuth
tienen el mismo peso, y el firmante potencial es el único que tiene un peso diferente.
Ten en cuenta que la cuenta creada arriba coincidirá con el primer criterio. Si se usara el esquema 2-3, entonces el segundo criterio coincidiría. (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 de bajo nivel signWithRecoveryServers
para firmar transacciones arbitrarias.
Finalmente, es hora de enviar la transacción:
- TypeScript
await stellar.submitTransaction(recoverTxn);