Skip to content

feat(token-factory): implementar módulo con endpoints para interactuar con el Token Factory Contract #39

@zkCaleb-dev

Description

@zkCaleb-dev

Descripción

Crear el módulo token-factory dentro de apps/core/src/ que exponga endpoints REST para interactuar con las funciones del contrato Token Factory ya desplegado. Este contrato implementa el estándar SEP-41 (token fungible de Soroban) y representa el token de participación que reciben los inversores.

Contexto de arquitectura

El módulo soroban ya provee el método buildContractCallTransaction en SorobanService:

// soroban/soroban.service.ts
async buildContractCallTransaction(
  contractId: string,
  method: string,
  args: Record<string, unknown>,
  callerPublicKey: string,
): Promise<string> {
  const client = await contract.Client.from({
    contractId,
    rpcUrl: this.rpcUrl,
    networkPassphrase: this.networkPassphrase,
    publicKey: callerPublicKey,
  });

  const tx = await (client)[method](args);
  return tx.toXDR();
}

Para operaciones de escritura el endpoint retorna { unsignedXdr } para que el cliente lo firme. Para operaciones de lectura se requiere el método readContractState(...) en SorobanService (introducido en el issue del Vault). El contractId de cada instancia de Token Factory se recibe dinámicamente en el request.

El patrón de módulo a replicar es el de deploy:

  • token-factory.module.ts
  • token-factory.service.ts
  • token-factory.controller.ts
  • dto/

Funciones del contrato Token Factory

Las funciones públicas del contrato (token-factory/src/contract.rs) son:

Escritura — retornan { unsignedXdr }:

Función del contrato Args en Rust Descripción
mint to: Address, amount: i128 Acuña tokens hacia una dirección (solo mint_authority)
set_admin new_admin: Address Transfiere la autoridad de acuñación a una nueva dirección
approve from: Address, spender: Address, amount: i128, expiration_ledger: u32 Aprueba que un spender gaste tokens en nombre de from
transfer from: Address, to_muxed: Address, amount: i128 Transfiere tokens entre direcciones
transfer_from spender: Address, from: Address, to: Address, amount: i128 Transfiere tokens usando allowance previamente aprobado
burn from: Address, amount: i128 Destruye tokens de una dirección
burn_from spender: Address, from: Address, amount: i128 Destruye tokens usando allowance

Lectura — retornan datos directamente:

Función del contrato Args en Rust Retorna
balance id: Address i128 — saldo de la dirección
allowance from: Address, spender: Address i128 — monto aprobado
decimals u32
name String
symbol String
escrow_id String — ID del escrow al que está vinculado el token

Estructura de archivos a crear

src/token-factory/
├── token-factory.controller.ts
├── token-factory.service.ts
├── token-factory.module.ts
└── dto/
    ├── mint.dto.ts
    ├── set-admin.dto.ts
    ├── approve.dto.ts
    ├── transfer.dto.ts
    ├── transfer-from.dto.ts
    ├── burn.dto.ts
    └── burn-from.dto.ts

Endpoints esperados

POST /token-factory/mint                       → { unsignedXdr }
POST /token-factory/set-admin                  → { unsignedXdr }
POST /token-factory/approve                    → { unsignedXdr }
POST /token-factory/transfer                   → { unsignedXdr }
POST /token-factory/transfer-from              → { unsignedXdr }
POST /token-factory/burn                       → { unsignedXdr }
POST /token-factory/burn-from                  → { unsignedXdr }

GET  /token-factory/balance?contractId=...&address=...          → { balance: string }
GET  /token-factory/allowance?contractId=...&from=...&spender=... → { allowance: string }
GET  /token-factory/decimals?contractId=...                     → { decimals: number }
GET  /token-factory/name?contractId=...                         → { name: string }
GET  /token-factory/symbol?contractId=...                       → { symbol: string }
GET  /token-factory/escrow-id?contractId=...                    → { escrowId: string }

Todos los DTOs de escritura incluyen contractId: string y callerPublicKey: string como campos requeridos. Los campos amount usan @IsNumber() y @IsPositive().

Tareas

  • Crear token-factory.module.ts y registrarlo en app.module.ts
  • Crear token-factory.service.ts con un método por función del contrato, usando this.soroban.buildContractCallTransaction(...) para escrituras y this.soroban.readContractState(...) para lecturas
  • Crear token-factory.controller.ts con los endpoints definidos arriba
  • Crear los DTOs con validaciones apropiadas (@IsString(), @IsNumber(), @IsPositive(), @IsNotEmpty())

Criterios de aceptación

  • Todos los endpoints de escritura retornan { unsignedXdr } ante un request válido
  • Los endpoints de lectura retornan los datos directamente
  • Los DTOs validan correctamente los tipos de dato
  • TokenFactoryModule queda registrado en AppModule
  • No se modifica la lógica existente de SorobanModule

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions