Recuperació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.
- TypeScript
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:
- 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 indica al servidor de recuperación qué identidades están autorizadas a 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 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:
- 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:
- Establezca
deviceKp
como la clave principal de la cuenta. Ten en cuenta que la clave maestra perteneciente aaccountKp
estará bloqueada.deviceKp
debe ser utilizado como firmante principal. - Establecer todos los umbrales de operación a 10. Puedes leer más sobre el umbral en la documentación
- 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) - 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:
- TypeScript
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:
- TypeScript
const authToken = await recovery
.sep10Auth(server1Key)
.authenticate({ accountKp: recoveryKp });
A continuación, obtén información de la cuenta usando 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 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.
- 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 autenticarnos 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 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.
- 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 se considerará una clave de dispositivo si se cumple una de estas condiciones:
- 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 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:
- TypeScript
await stellar.submitTransaction(recoverTxn);