Skip to content

Commit c042ea1

Browse files
Added more details on recovering wallet from storage and smart contract return types (#201)
* added more details on recovering wallet from storage * chore(i18n): update translations [en] Sync file structure, format locales. Branch: 201/merge * explanation for return types * chore(i18n): update translations [en] Sync file structure, format locales. Branch: 201/merge --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 315295f commit c042ea1

15 files changed

Lines changed: 408 additions & 57 deletions

File tree

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
---
2+
title: Recuperación segura de sesión
3+
description: El SDK ofrece la opción de almacenar la información de la wallet de sesión de forma segura en ciertas plataformas utilizando el almacenamiento seguro nativo.
4+
---
5+
6+
# Recuperación de sesiones
7+
Por defecto, el SDK requerirá que los usuarios inicien sesión cada vez que la aplicación se cierre completamente. Esto se debe a que, por defecto, no guardamos la información de la wallet de sesión (por ejemplo, claves privadas) en ningún tipo de almacenamiento persistente para proteger la seguridad del usuario.
8+
9+
Sin embargo, en ciertas plataformas, hemos integrado el almacenamiento seguro nativo de la plataforma.
10+
11+
Si habilita `StoreSessionPrivateKeyInSecureStorage` en su ScriptableObject `SequenceConfig`, almacenaremos automáticamente la información de la wallet de sesión (en plataformas compatibles) y expondremos la opción de intentar recuperar la sesión en `SequenceLogin`. La `SequenceLoginWindow` predeterminada gestionará automáticamente este flujo de UI también (consulte [Autenticación](/sdk/unity/onboard/authentication/intro)). Si la plataforma no es compatible, esta opción no tendrá efecto.
12+
13+
A continuación puede ver las plataformas compatibles y aprender sobre la solución de almacenamiento seguro de cada una; es importante entender los conceptos básicos de cómo funcionan estos sistemas y pensar cuidadosamente en las implicaciones de seguridad de almacenar claves privadas (o cualquier secreto) en almacenamiento persistente.
14+
15+
## Integración
16+
Tiene dos opciones para recuperar una wallet desde el almacenamiento. La primera es usar la clase `EmbeddedWalletAdapter`. Si esta llamada tiene éxito, el `EmbeddedWalletAdapter` contendrá la instancia de Wallet.
17+
18+
```csharp
19+
bool recovered = await EmbeddedWalletAdapter.GetInstance().TryRecoverWalletFromStorage();
20+
```
21+
22+
De lo contrario, utilice la clase subyacente `SequenceLogin`.
23+
24+
```csharp
25+
(bool storageEnabled, IWallet wallet) = await SequenceLogin.GetInstance().TryToRestoreSessionAsync();
26+
```
27+
28+
En ambos casos, puede escuchar el evento `SequenceWallet.OnWalletCreated` cada vez que una wallet se recupere del almacenamiento o se cree durante el proceso de inicio de sesión.
29+
30+
## Detalles de la plataforma
31+
32+
### Editor
33+
En el editor, usamos PlayerPrefs para almacenar la clave privada. También deberá habilitar `EditorStoreSessionPrivateKeyInSecureStorage` en SequenceConfig para usar el almacenamiento seguro y recuperar sesiones dentro del editor. Esta bandera separada le facilita probar ambos flujos sin modificar el comportamiento de sus builds. El almacenamiento seguro en el editor es solo para fines de desarrollo y no debe considerarse seguro para almacenamiento a largo plazo.
34+
35+
### iOS
36+
En iOS, utilizamos el [iOS Keychain](https://developer.apple.com/documentation/security/keychain_services?language=objc).
37+
38+
### MacOS
39+
En MacOS, utilizamos el [MacOS Keychain](https://developer.apple.com/documentation/security/keychain_services?language=objc).
40+
41+
### Windows
42+
En PCs con Windows, utilizamos la [Crypto: Next Generation - Data Protection API (CNG DPAPI)](https://learn.microsoft.com/en-us/windows/win32/seccng/cng-dpapi)
43+
44+
### Web
45+
En compilaciones Web, utilizamos [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) a través de [PlayerPrefs](https://docs.unity3d.com/ScriptReference/PlayerPrefs.html).
46+
47+
### Android
48+
En compilaciones Android, utilizamos el [Android Keystore](https://developer.android.com/privacy-and-security/keystore).
49+
50+
El primer paso es importar el plugin `AndroidKeyBridge.java` en su carpeta Assets. Esto se hace fácilmente desde Samples en el package manager; simplemente importe el sample titulado `Android Secure Storage`.
51+
52+
Nuestro plugin Keystore para Unity (incluido en el SDK) requiere una Plantilla Gradle Principal personalizada. Por favor, vaya a la configuración de su proyecto y, en `Player > Publishing Settings`, habilite `Custom Main Gradle Template`. Esto creará un archivo `Assets/Plugins/Android/mainTemplate.gradle` (o similar; el editor le mostrará la ruta) si aún no tiene uno. Aquí tiene un ejemplo de archivo `mainTemplate.gradle`; por favor, copie/pegue (o incorpore en su archivo existente).
53+
54+
```
55+
apply plugin: 'com.android.library'
56+
**APPLY_PLUGINS**
57+
58+
dependencies {
59+
implementation fileTree(dir: 'libs', include: ['*.jar'])
60+
implementation 'androidx.security:security-crypto:1.1.0-alpha03'
61+
62+
**DEPS**}
63+
64+
android {
65+
compileSdkVersion **APIVERSION**
66+
buildToolsVersion '**BUILDTOOLS**'
67+
68+
compileOptions {
69+
sourceCompatibility JavaVersion.VERSION_1_8
70+
targetCompatibility JavaVersion.VERSION_1_8
71+
}
72+
73+
defaultConfig {
74+
minSdkVersion **MINSDKVERSION**
75+
targetSdkVersion **TARGETSDKVERSION**
76+
ndk {
77+
abiFilters **ABIFILTERS**
78+
}
79+
versionCode **VERSIONCODE**
80+
versionName '**VERSIONNAME**'
81+
consumerProguardFiles 'proguard-unity.txt'**USER_PROGUARD**
82+
}
83+
84+
lintOptions {
85+
abortOnError false
86+
}
87+
88+
aaptOptions {
89+
noCompress = **BUILTIN_NOCOMPRESS** + unityStreamingAssets.tokenize(', ')
90+
ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~"
91+
}**PACKAGING_OPTIONS**
92+
}**REPOSITORIES**
93+
**IL_CPP_BUILD_SETUP**
94+
**SOURCE_BUILD_SETUP**
95+
**EXTERNAL_SOURCES**
96+
```
97+
98+
Nuestro plugin Keystore también requiere una Plantilla de Propiedades Gradle personalizada. Nuevamente, vaya a la configuración de su proyecto y, en `Player > Publishing Settings`, habilite `Custom Gradle Properties Template`. Esto creará un archivo `Assets/Plugins/Android/gradleTemplate.properties` (o similar; el editor le mostrará la ruta) si aún no tiene uno. Aquí tiene un ejemplo de archivo `gradleTemplate.properties`; por favor, copie/pegue (o incorpore en su archivo existente).
99+
100+
```
101+
org.gradle.jvmargs=-Xmx**JVM_HEAP_SIZE**M
102+
org.gradle.parallel=true
103+
android.enableJetifier=true
104+
android.useAndroidX=true
105+
unityStreamingAssets=**STREAMING_ASSETS**
106+
**ADDITIONAL_PROPERTIES**
107+
108+
android.enableR8=**MINIFY_WITH_R_EIGHT**
109+
```
110+
111+
## Solución de problemas
112+
Si tiene problemas con el almacenamiento seguro o Google Sign-In en Android, siga estos pasos de solución de problemas.
113+
- **Google Sign-In:** Asegúrese de que el valor `data android:scheme` en su archivo `AndroidManifest.xml` coincida con el `Url Scheme` en su archivo
114+
`SequenceConfig.asset`. Verifique que esté todo en minúsculas.
115+
- **Almacenamiento seguro:** Asegúrese de que su `mainTemplate.gradle` defina correctamente el plugin `androidx.security:security-crypto` y que no sea
116+
sobrescrito por otro plugin o por el Android Plugin Resolver.
117+
- **Pruebe nuestra demo:** [Instale nuestra build de demostración](https://drive.google.com/file/d/1rAvnPu56Hj3yDRL32_lr887xt-xMQoYK/view?usp=sharing)
118+
y asegúrese de que funcione correctamente en su dispositivo.
119+
- Compare la configuración de su proyecto Unity (AndroidManifest, archivos gradle, configuración del reproductor de Android) con nuestro [proyecto sdk.](https://github.com/0xsequence/sequence-unity)
120+
- **Ideas adicionales:** Desinstale la app antes de instalar una nueva build, cambie su esquema de URL o el bundle id.

es/sdk/unity/onboard/session-management.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Gestión de sesiones en Unity — Documentación de Sequence
2+
title: Gestión de Sesiones
33
---
44

55
Una vez que haya autenticado a su usuario con las APIs de Sequence y establecido una sesión, tiene disponibles varios métodos para gestionar la sesión.
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
---
2+
title: Smart Contracts
3+
---
4+
5+
Crear un objeto `Contract` para un contrato ya desplegado es bastante sencillo.
6+
7+
```csharp
8+
Contract contract = new Contract(contractAddress, abi);
9+
```
10+
11+
Aunque no es estrictamente necesario, se recomienda <i>encarecidamente</i> proporcionar el ABI del contrato como una cadena al crear un objeto contract. Si no lo hace, no podrá aprovechar completamente nuestra codificación y decodificación ABI.
12+
Si decide seguir este camino, deberá proporcionar la firma completa de la función (nombre de la función + tipos de parámetros entre paréntesis - por ejemplo, transfer(address,uint256) para el método transfer de ERC20) al llamar a una función o consultar el contrato, y solo recibirá una cadena como respuesta a las consultas.
13+
14+
## Llamar funciones de Smart Contract
15+
Para llamar a un smart contract, usará el método `CallFunction` para crear un objeto `CallContractFunction`, que determinará el gasPrice, gasLimit, nonce y data apropiados para incluir en un nuevo `EthTransaction` al proporcionarle un cliente y un objeto `ContractCall` al método `Create` async Task
16+
17+
Un ejemplo de cómo llamar a un smart contract sería el siguiente:
18+
19+
```csharp
20+
Contract erc20Contract = new Contract(contractAddress, contractAbi); // We'll use the well-known ERC20 contract as our example case
21+
TransactionReceipt receipt = await erc20Contract.CallFunction("transfer", toAddress, amountAsBigInteger).SendTransactionMethodAndWaitForReceipt(wallet, client);
22+
```
23+
24+
Nota: si no desea esperar el recibo, puede usar `SendTransactionMethod` en su lugar.
25+
26+
Alternativamente, si solo quiere crear el `EthTransaction` y enviarlo más tarde, puede usar directamente el objeto `CallContractFunction` de `CallFunction`.
27+
28+
```csharp
29+
Contract erc20Contract = new Contract(contractAddress, contractAbi); // We'll use the well-known ERC20 contract as our example case
30+
EthTransaction transaction = await erc20Contract.CallFunction("transfer", toAddress, amountAsBigInteger).Create(client, new ContractCall(wallet.GetAddress()));
31+
TransactionReceipt receipt = await wallet.SendTransactionAndWaitForReceipt(client, transaction);
32+
33+
// or
34+
CallContractFunction transactionCreator = erc20Contract.CallFunction("transfer", toAddress, amountAsBigInteger);
35+
EthTransaction transaction = await transactionCreator.Create(client, new ContractCall(wallet.GetAddress()));
36+
TransactionReceipt receipt = await wallet.SendTransactionAndWaitForReceipt(client, transaction);
37+
38+
// or
39+
CallContractFunction transactionCreator = erc20Contract.CallFunction("transfer", toAddress, amountAsBigInteger);
40+
TransactionReceipt receipt = await transactionCreator.SendTransactionMethodAndWaitForReceipt(wallet, client);
41+
```
42+
43+
Notará que el método `CallFunction` acepta un número arbitrario de argumentos. Debe proporcionar los argumentos en el orden en que aparecen en el ABI/firma de la función.
44+
45+
## Comprendiendo los mapeos de tipos de datos
46+
Al interactuar con smart contracts, es importante entender cómo los tipos de datos de EVM se mapean a los tipos de datos de C# en la librería SequenceEthereum.
47+
48+
Por ejemplo, si proporciona una cadena donde el ABI espera un entero, recibirá una excepción, incluso si esa cadena podría convertirse en un entero.
49+
50+
### Address
51+
En C# puede usar un tipo `string` o crear una instancia de `Address`. Asegúrese de que su cadena sea hexadecimal,
52+
comience con `0x` y tenga una longitud fija de 42 caracteres.
53+
54+
```csharp
55+
Address address = new Address("0x123...");
56+
```
57+
58+
### Enteros
59+
Para tipos de enteros como `int256`, `uint8` o `uint256` use el tipo `BigInteger` de System.Numerics.
60+
61+
```csharp
62+
// Simple number
63+
BigInteger number = new BigInteger(10000);
64+
65+
// From hex
66+
string hexString = "0x0000000...01";
67+
BigInteger number = hexString.HexStringToBigInteger();
68+
```
69+
70+
### Bytes
71+
Para definir tipos de datos byte de Solidity en C#, tiene la opción de crear un `FixedByte` para tipos como `byte16` o `byte32`.
72+
Cuando su contrato requiera `bytes`, puede convertir cualquier valor en un `byte[]` de cualquier longitud.
73+
74+
Si sus datos están representados como una cadena hexadecimal en C#, asegúrese de usar nuestra función `HexStringToByteArray()` para convertir
75+
el valor hexadecimal de vuelta al arreglo de bytes original.
76+
77+
Para arreglos de bytes como `byte32[]`, simplemente cree un `FixedByte[]` en C#.
78+
79+
```csharp
80+
// byte16 or byte32
81+
new FixedByte(16, new byte[] {});
82+
83+
// bytes
84+
string someString = "abc0123456789";
85+
byte[] bytes = someString.ToByteArray();
86+
87+
// signature
88+
string signature = "0x0ab123...";
89+
byte[] bytes = signature.HexStringToByteArray();
90+
```
91+
92+
### Structs
93+
Use Tuples para llamar una función on-chain con un struct. Aquí hay un ejemplo de un struct en Solidity y cómo definirlo
94+
usando el SDK de Unity de Sequence y pasarlo como argumento en una función `Contract.CallFunction`.
95+
96+
Struct de Solidity
97+
98+
```solidity
99+
struct ExampleStruct {
100+
address wallet;
101+
uint256 amount;
102+
byte32 data;
103+
}
104+
```
105+
106+
Equivalente en C#
107+
108+
```csharp
109+
Address wallet = new Address("0x...");
110+
BigInteger amount = new BigInteger(10000);
111+
FixedByte data = new FixedByte(32, byteArrayData);
112+
var arg = new Tuple<Address, BigInteger, FixedByte>(wallet, amount, data);
113+
```
114+
115+
### Otros tipos
116+
Para tipos de datos tradicionales en Solidity como `string` o `bool`, puede usar los mismos tipos de datos en C#.
117+
118+
### Tipos de retorno
119+
Cuando lea datos de un smart contract y utilice la función `Contract.SendQuery<TType>()`, puede usar TType para tipos de retorno simples como `string`, `BigInteger` o `bool`. Para tipos de retorno complejos como structs, use un `object[]` y analice manualmente los valores en su struct de C#.
120+
121+
```csharp
122+
// Let's consider a struct with the following variables: SomeStruct { address value1; uint256 value2; }
123+
object[] structValues = Contract.SendQuery<object[]>("SomeFunction");
124+
125+
SomeStruct newStruct = new SomeStruct() {
126+
Value1 = new Address(structValues[0].ToString()),
127+
Value2 = BigInteger.Parse(structValues[1].ToString())
128+
}
129+
```
130+
131+
## Consultar contratos
132+
Para consultar un smart contract (leer datos), use el método `SendQuery<T>` para consultar el contrato y devolver el resultado como tipo T (si es posible).
133+
Un ejemplo de cómo consultar un smart contract sería:
134+
135+
```csharp
136+
Contract erc20Contract = new Contract(contractAddress, contractAbi); // We'll use the well-known ERC20 contract as our example case
137+
BigIntegar balance = await erc20Contract.SendQuery<BigIntegar>(client, "balanceOf", address);
138+
```
139+
140+
Alternativamente, si desea simplemente construir la consulta y enviarla más tarde, puede usar `QueryContract<T>` para crear un delegado.
141+
142+
```csharp
143+
Contract erc20Contract = new Contract(contractAddress, contractAbi); // We'll use the well-known ERC20 contract as our example case
144+
QueryContractMessageSender<BigIntegar> balanceQuery = erc20Contract.QueryContract<BigIntegar>("balanceOf", address);
145+
BigIntegar balance = await balanceQuery(client);
146+
// or
147+
BigIntegar balance = await balanceQuery.SendQuery(client);
148+
```
149+
150+
## Desplegar contratos
151+
Si desea desplegar un contrato, puede usar el `ContractDeployer`
152+
153+
```csharp
154+
ContractDeploymentResult deploymentResult = await ContractDeployer.Deploy(client, wallet, contractBytecodeAsString);
155+
string newlyDeployedContractAddress = deploymentResult.Receipt.contractAddress;
156+
```

es/sdk/unity/quickstart.mdx

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
---
2-
title: Guía rápida de Unity
2+
title: Inicio rápido
33
description: Documentación de inicio rápido para el SDK de Unity de Sequence.
44
---
55

66
<Steps>
77
<Step title="Instalar el SDK de Unity">
8-
Instale la última versión del SDK de Unity de Sequence desde [OpenUPM](/sdk/unity/installation#openupm),
9-
o utilice la [interfaz del Package Manager de Unity](/sdk/unity/installation#or-using-package-manager-ui)
10-
y use la siguiente URL de Git: `https://github.com/0xsequence/sequence-unity.git?path=/Packages/Sequence-Unity`
8+
Instale la última versión del Unity SDK de Sequence desde [OpenUPM](/sdk/unity/installation#openupm),
9+
o utilice [Unity's Package Manager UI](/sdk/unity/installation#or-using-package-manager-ui)
10+
y use la siguiente URL de Git `https://github.com/0xsequence/sequence-unity.git?path=/Packages/Sequence-Unity`
1111
</Step>
1212

1313
<Step title="Configure el SDK">
@@ -23,11 +23,15 @@ description: Documentación de inicio rápido para el SDK de Unity de Sequence.
2323
</Step>
2424

2525
<Step title="Integre su proceso de inicio de sesión">
26-
Comience estableciendo una sesión de wallet usando un OTP enviado por correo electrónico. Importe el ejemplo `Setup` desde el Package Manager UI,
27-
lo que colocará un conjunto de plantillas en su proyecto dentro del directorio `Resources/`.
28-
Cree el [Login Boilerplate](/sdk/unity/bootstrap_game#login) para enviar una contraseña de un solo uso al correo electrónico especificado.
26+
Comience verificando si hay una sesión de wallet disponible en el almacenamiento:
2927

30-
Una vez que haya integrado sus primeras funciones, puede continuar con [proveedores de inicio de sesión adicionales](/sdk/unity/onboard/authentication/intro)
28+
```csharp
29+
bool recovered = await EmbeddedWalletAdapter.GetInstance().TryRecoverWalletFromStorage();
30+
```
31+
32+
Si eso devuelve `false`, debe pedirle al usuario que inicie sesión. Importe el ejemplo `Setup` desde la interfaz del Package Manager UI, lo que colocará un conjunto de plantillas en su proyecto dentro del directorio `Resources/`. Cree el [Login Boilerplate](/sdk/unity/bootstrap_game#login) para enviar una contraseña de un solo uso al correo electrónico especificado.
33+
34+
Una vez que haya integrado sus primeras funciones, puede continuar con [proveedores de inicio de sesión adicionales](/sdk/unity/onboard/authentication/intro)
3135
como Google, Apple o PlayFab.
3236

3337
```csharp
@@ -40,9 +44,9 @@ description: Documentación de inicio rápido para el SDK de Unity de Sequence.
4044
</Step>
4145

4246
<Step title="Pruebe las funciones de Sequence">
43-
El SDK de Unity de Sequence incluye una variedad de [Boilerplates](/sdk/unity/bootstrap_game) para ayudarte a iniciar tu juego rápidamente.
44-
Una vez que todo esté configurado, puedes crear prefabs para mostrar un Perfil de Jugador, Inventario o Tienda dentro del juego.
45-
Consulta [cómo integrar un Perfil de Jugador.](/sdk/unity/bootstrap_game#player-profile)
47+
El SDK de Unity de Sequence incluye una variedad de [boilerplates](/sdk/unity/bootstrap_game) para ayudarle a iniciar su juego rápidamente.
48+
Cuando todo esté configurado, puede crear prefabs para mostrar el perfil del jugador, el inventario o la tienda dentro del juego.
49+
Vea [cómo integrar un perfil de jugador.](/sdk/unity/bootstrap_game#player-profile)
4650

4751
```csharp
4852
BoilerplateFactory.OpenSequencePlayerProfile(parent, wallet, chain);
@@ -54,8 +58,8 @@ description: Documentación de inicio rápido para el SDK de Unity de Sequence.
5458
</Step>
5559

5660
<Step title="Intégrelo por su cuenta">
57-
Comience con `EmbeddedWalletAdapter` para iniciar su integración rápidamente con solo unas pocas líneas de código y estará listo para empezar.
58-
Cuando desee personalizar su integración, consulte nuestra otra documentación como [autenticando usuarios](/sdk/unity/onboard/authentication/intro) o [cómo enviar transacciones](/sdk/unity/power/write-to-blockchain).
61+
Comience con `EmbeddedWalletAdapter` para iniciar su integración rápidamente con solo unas líneas de código y estará listo para comenzar.
62+
Cuando quiera personalizar su integración, consulte nuestra documentación sobre [autenticación de usuarios](/sdk/unity/onboard/authentication/intro) o [cómo enviar transacciones.](/sdk/unity/power/write-to-blockchain)
5963

6064
```csharp
6165
EmbeddedWalletAdapter adapter = EmbeddedWalletAdapter.GetInstance();

es/sdk/unity/setup.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
---
2-
title: Configuración en Unity
2+
title: Configuración
33
description: Documentación para la configuración del SDK de Unity para la infraestructura de Sequence orientada a juegos web3.
44
---
55

6-
# Setup
6+
# Configuración
77

88
1. [Configure su Embedded Wallet](/sdk/headless-wallet/quickstart) en el Sequence Builder
99
2. Descargue el ScriptableObject de configuración de Unity `SequenceConfig.asset` desde la interfaz de Builder

0 commit comments

Comments
 (0)