fix: compilation WASM réussie avec sdk_common docker-support - Correction de la branche sdk_common vers docker-support - Correction de l'import scan_blocks manquant - Compilation TypeScript réussie - Build de production fonctionnel
This commit is contained in:
parent
252398b52d
commit
39c010ace7
1
pkg/.gitignore
vendored
Normal file
1
pkg/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*
|
347
pkg/README.md
Normal file
347
pkg/README.md
Normal file
@ -0,0 +1,347 @@
|
||||
# 🚀 4NK Node - Infrastructure Docker Complète
|
||||
|
||||
Infrastructure Docker complète pour le développement et le déploiement de services 4NK avec support des paiements silencieux (Silent Payments).
|
||||
|
||||
## 📋 Table des Matières
|
||||
|
||||
- [🏗️ Architecture](#️-architecture)
|
||||
- [🚀 Démarrage Rapide](#-démarrage-rapide)
|
||||
- [📚 Documentation](#-documentation)
|
||||
- [🔧 Configuration](#-configuration)
|
||||
- [🧪 Tests et Monitoring](#-tests-et-monitoring)
|
||||
- [🌐 Réseau de Relais](#-réseau-de-relais)
|
||||
- [🛠️ Développement](#️-développement)
|
||||
- [🚨 Dépannage](#-dépannage)
|
||||
|
||||
## 🏗️ Architecture
|
||||
|
||||
4NK Node est composé de plusieurs services orchestrés via Docker :
|
||||
|
||||
| Service | Port | Description | Statut |
|
||||
|---------|------|-------------|---------|
|
||||
| **Tor** | 9050, 9051 | Proxy anonyme pour Bitcoin Core | ✅ Stable |
|
||||
| **Bitcoin Core** | 18443 (RPC), 29000 (ZMQ) | Nœud Bitcoin en mode signet | ✅ Stable |
|
||||
| **Blindbit** | 8000 | Service de filtres pour les paiements silencieux | ✅ Stable |
|
||||
| **sdk_relay** | 8090-8095 | Services de relais (3 instances) | ✅ Stable |
|
||||
|
||||
### 🔄 Flux de Données
|
||||
|
||||
```
|
||||
Client → sdk_relay → Bitcoin Core
|
||||
↓
|
||||
Blindbit → Bitcoin Core
|
||||
↓
|
||||
Tor (anonymat)
|
||||
```
|
||||
|
||||
## 🚀 Démarrage Rapide
|
||||
|
||||
### Prérequis
|
||||
|
||||
- **Docker** et **Docker Compose** installés
|
||||
- **10 Go** d'espace disque minimum
|
||||
- **Connexion Internet** stable
|
||||
- **Clé SSH** configurée pour GitLab (recommandé)
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# 1. Cloner le repository (SSH recommandé)
|
||||
git clone git@git.4nkweb.com:4nk/4NK_node.git
|
||||
cd 4NK_node
|
||||
|
||||
# 2. Démarrer tous les services
|
||||
./restart_4nk_node.sh
|
||||
|
||||
# 3. Vérifier le statut
|
||||
docker ps
|
||||
```
|
||||
|
||||
### Configuration SSH (Recommandé)
|
||||
|
||||
```bash
|
||||
# Générer une clé SSH
|
||||
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_4nk -C "4nk-automation"
|
||||
|
||||
# Ajouter à l'agent SSH
|
||||
ssh-add ~/.ssh/id_ed25519_4nk
|
||||
|
||||
# Configurer Git
|
||||
git config --global core.sshCommand "ssh -i ~/.ssh/id_ed25519_4nk"
|
||||
|
||||
# Ajouter la clé publique à GitLab
|
||||
cat ~/.ssh/id_ed25519_4nk.pub
|
||||
```
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
### 📖 Guides Principaux
|
||||
|
||||
- **[Guide d'Installation](docs/INSTALLATION.md)** - Installation et configuration complète
|
||||
- **[Guide d'Utilisation](docs/USAGE.md)** - Utilisation quotidienne et cas d'usage
|
||||
- **[Guide de Configuration](docs/CONFIGURATION.md)** - Configuration avancée
|
||||
- **[Guide de Développement](docs/DEVELOPMENT.md)** - Développement et contribution
|
||||
|
||||
### 🔧 Guides Techniques
|
||||
|
||||
- **[Architecture Technique](docs/ARCHITECTURE.md)** - Architecture détaillée
|
||||
- **[API Reference](docs/API.md)** - Documentation des APIs
|
||||
- **[Sécurité](docs/SECURITY.md)** - Sécurité et bonnes pratiques
|
||||
- **[Performance](docs/PERFORMANCE.md)** - Optimisation et monitoring
|
||||
|
||||
### 🧪 Guides de Test
|
||||
|
||||
- **[Tests de Base](docs/TESTING.md)** - Tests de connectivité et fonctionnalité
|
||||
- **[Tests de Synchronisation](docs/SYNC_TESTING.md)** - Tests de synchronisation entre relais
|
||||
- **[Tests de Performance](docs/PERFORMANCE_TESTING.md)** - Tests de charge et performance
|
||||
|
||||
### 🌐 Guides Réseau
|
||||
|
||||
- **[Réseau de Relais](docs/RELAY_NETWORK.md)** - Configuration du réseau mesh
|
||||
- **[Nœuds Externes](docs/EXTERNAL_NODES.md)** - Ajout et gestion de nœuds externes
|
||||
- **[Synchronisation](docs/SYNCHRONIZATION.md)** - Protocole de synchronisation
|
||||
|
||||
## 🔧 Configuration
|
||||
|
||||
### Services Disponibles
|
||||
|
||||
| Service | Configuration | Volume | Description |
|
||||
|---------|---------------|---------|-------------|
|
||||
| **Bitcoin Core** | `bitcoin/bitcoin.conf` | `bitcoin_data` | Nœud Bitcoin signet avec RPC et ZMQ |
|
||||
| **Blindbit** | `blindbit/blindbit.toml` | `blindbit_data` | Service de filtres Silent Payments |
|
||||
| **sdk_relay** | `sdk_relay/.conf.docker.*` | `sdk_relay_*_data` | Relais avec synchronisation mesh |
|
||||
| **Tor** | `tor/torrc` | - | Proxy anonyme |
|
||||
|
||||
### Variables d'Environnement
|
||||
|
||||
```bash
|
||||
# Logs
|
||||
RUST_LOG=debug,bitcoincore_rpc=trace
|
||||
|
||||
# Bitcoin
|
||||
BITCOIN_COOKIE_PATH=/home/bitcoin/.bitcoin/signet/.cookie
|
||||
|
||||
# Synchronisation
|
||||
ENABLE_SYNC_TEST=1
|
||||
```
|
||||
|
||||
## 🧪 Tests et Monitoring
|
||||
|
||||
### Tests de Base
|
||||
|
||||
```bash
|
||||
# Test de connectivité
|
||||
./test_final_sync.sh
|
||||
|
||||
# Test de synchronisation
|
||||
./test_sync_logs.sh
|
||||
|
||||
# Test des messages WebSocket
|
||||
python3 test_websocket_messages.py
|
||||
```
|
||||
|
||||
### Monitoring
|
||||
|
||||
```bash
|
||||
# Surveillance de la synchronisation
|
||||
./monitor_sync.sh
|
||||
|
||||
# Logs en temps réel
|
||||
docker-compose logs -f
|
||||
|
||||
# Statut des services
|
||||
docker ps
|
||||
```
|
||||
|
||||
### Tests de Performance
|
||||
|
||||
```bash
|
||||
# Test de charge WebSocket
|
||||
python3 test_websocket_messages.py --load-test
|
||||
|
||||
# Test de synchronisation
|
||||
./test_sync_logs.sh continuous
|
||||
```
|
||||
|
||||
## 🌐 Réseau de Relais
|
||||
|
||||
### Architecture Mesh
|
||||
|
||||
L'infrastructure supporte un réseau mesh de relais avec :
|
||||
|
||||
- **3 relais locaux** : `sdk_relay_1`, `sdk_relay_2`, `sdk_relay_3`
|
||||
- **Nœuds externes** : Configuration via `external_nodes.conf`
|
||||
- **Synchronisation automatique** : Partage de données entre relais
|
||||
- **Découverte automatique** : Découverte des relais voisins
|
||||
|
||||
### Ajout de Nœuds Externes
|
||||
|
||||
```bash
|
||||
# Ajouter un nœud externe
|
||||
./add_external_node.sh add external-relay-1 external-relay-1.example.com:8090
|
||||
|
||||
# Lister les nœuds configurés
|
||||
./add_external_node.sh list
|
||||
|
||||
# Tester la connectivité
|
||||
./add_external_node.sh test external-relay-1
|
||||
```
|
||||
|
||||
### Configuration Externe
|
||||
|
||||
```toml
|
||||
# external_nodes.conf
|
||||
[relays]
|
||||
external-relay-1 = "external-relay-1.example.com:8090"
|
||||
dev3-relay = "dev3.4nkweb.com:443"
|
||||
|
||||
[discovery]
|
||||
auto_discover = true
|
||||
bootstrap_nodes = []
|
||||
```
|
||||
|
||||
## 🛠️ Développement
|
||||
|
||||
### Structure du Projet
|
||||
|
||||
```
|
||||
4NK_node/
|
||||
├── bitcoin/ # Configuration Bitcoin Core
|
||||
├── blindbit/ # Configuration Blindbit
|
||||
├── sdk_relay/ # Configuration des relais
|
||||
├── tor/ # Configuration Tor
|
||||
├── specs/ # Spécifications techniques
|
||||
├── docs/ # Documentation
|
||||
├── tests/ # Scripts de test
|
||||
├── scripts/ # Scripts utilitaires
|
||||
└── docker-compose.yml
|
||||
```
|
||||
|
||||
### Ajout d'un Nouveau Service
|
||||
|
||||
1. Créer le Dockerfile dans un sous-répertoire
|
||||
2. Ajouter le service dans `docker-compose.yml`
|
||||
3. Configurer les dépendances et le réseau
|
||||
4. Ajouter les healthchecks si nécessaire
|
||||
5. Documenter dans la section appropriée
|
||||
|
||||
### Modification de la Configuration
|
||||
|
||||
```bash
|
||||
# Modifier la configuration Bitcoin Core
|
||||
sudo docker-compose down
|
||||
# Éditer bitcoin/bitcoin.conf
|
||||
sudo docker-compose up -d bitcoin
|
||||
|
||||
# Modifier la configuration Blindbit
|
||||
# Éditer blindbit/blindbit.toml
|
||||
sudo docker-compose restart blindbit
|
||||
```
|
||||
|
||||
## 🚨 Dépannage
|
||||
|
||||
### Problèmes Courants
|
||||
|
||||
#### 1. Ports Déjà Utilisés
|
||||
|
||||
```bash
|
||||
# Vérifier les ports utilisés
|
||||
sudo netstat -tlnp | grep -E "(18443|8000|9050|8090)"
|
||||
|
||||
# Arrêter les services conflictuels
|
||||
sudo docker-compose down
|
||||
```
|
||||
|
||||
#### 2. Problèmes de Synchronisation Bitcoin
|
||||
|
||||
```bash
|
||||
# Vérifier les logs Bitcoin Core
|
||||
sudo docker-compose logs bitcoin
|
||||
|
||||
# Redémarrer Bitcoin Core
|
||||
sudo docker-compose restart bitcoin
|
||||
```
|
||||
|
||||
#### 3. Problèmes de Connectivité sdk_relay
|
||||
|
||||
```bash
|
||||
# Tester la connectivité
|
||||
cd sdk_relay
|
||||
./test_final.sh
|
||||
|
||||
# Vérifier la configuration
|
||||
./debug_container.sh
|
||||
```
|
||||
|
||||
### Logs Détaillés
|
||||
|
||||
```bash
|
||||
# Logs avec timestamps
|
||||
sudo docker-compose logs -t
|
||||
|
||||
# Logs des 100 dernières lignes
|
||||
sudo docker-compose logs --tail=100
|
||||
|
||||
# Logs depuis une date
|
||||
sudo docker-compose logs --since="2024-01-01T00:00:00"
|
||||
```
|
||||
|
||||
### Healthchecks
|
||||
|
||||
```bash
|
||||
# Vérifier l'état des healthchecks
|
||||
sudo docker-compose ps
|
||||
|
||||
# Logs des healthchecks
|
||||
sudo docker-compose logs | grep health
|
||||
|
||||
# Test manuel du healthcheck sdk_relay
|
||||
sudo docker exec sdk_relay /usr/local/bin/healthcheck.sh
|
||||
```
|
||||
|
||||
## 📈 Performance
|
||||
|
||||
### Ressources Recommandées
|
||||
|
||||
- **CPU** : 2 cœurs minimum, 4 cœurs recommandés
|
||||
- **RAM** : 4 Go minimum, 8 Go recommandés
|
||||
- **Stockage** : 20 Go minimum pour la blockchain signet
|
||||
- **Réseau** : Connexion stable pour la synchronisation
|
||||
|
||||
### Optimisations
|
||||
|
||||
```bash
|
||||
# Limiter l'utilisation CPU
|
||||
sudo docker-compose up -d --scale bitcoin=1
|
||||
|
||||
# Surveiller l'utilisation des ressources
|
||||
sudo docker stats
|
||||
|
||||
# Optimiser l'espace disque
|
||||
sudo docker system prune -f
|
||||
```
|
||||
|
||||
## 🤝 Contribution
|
||||
|
||||
1. Fork le repository
|
||||
2. Créer une branche feature (`git checkout -b feature/nouvelle-fonctionnalite`)
|
||||
3. Commit les changements (`git commit -am 'Ajout de nouvelle fonctionnalité'`)
|
||||
4. Push la branche (`git push origin feature/nouvelle-fonctionnalite`)
|
||||
5. Créer une Pull Request
|
||||
|
||||
## 📄 Licence
|
||||
|
||||
Ce projet est sous licence MIT. Voir le fichier LICENSE pour plus de détails.
|
||||
|
||||
## 🆘 Support
|
||||
|
||||
Pour obtenir de l'aide :
|
||||
|
||||
1. Consulter la [documentation](docs/)
|
||||
2. Vérifier les [issues existantes](https://git.4nkweb.com/4nk/4NK_node/issues)
|
||||
3. Créer une nouvelle issue avec les détails du problème
|
||||
4. Inclure les logs et la configuration utilisée
|
||||
|
||||
---
|
||||
|
||||
**✨ Infrastructure 4NK Node - Prête pour la production !**
|
17
pkg/package.json
Normal file
17
pkg/package.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "sdk_client",
|
||||
"type": "module",
|
||||
"version": "0.1.0",
|
||||
"files": [
|
||||
"sdk_client_bg.wasm",
|
||||
"sdk_client.js",
|
||||
"sdk_client_bg.js",
|
||||
"sdk_client.d.ts"
|
||||
],
|
||||
"main": "sdk_client.js",
|
||||
"types": "sdk_client.d.ts",
|
||||
"sideEffects": [
|
||||
"./sdk_client.js",
|
||||
"./snippets/*"
|
||||
]
|
||||
}
|
355
pkg/sdk_client.d.ts
vendored
Normal file
355
pkg/sdk_client.d.ts
vendored
Normal file
@ -0,0 +1,355 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export function setup(): void;
|
||||
export function get_address(): string;
|
||||
export function get_member(): Member;
|
||||
export function restore_device(device: any): void;
|
||||
export function create_device_from_sp_wallet(sp_wallet: string): string;
|
||||
export function create_new_device(birthday: number, network_str: string): string;
|
||||
export function is_paired(): boolean;
|
||||
export function pair_device(process_id: string, sp_addresses: string[]): void;
|
||||
export function unpair_device(): void;
|
||||
export function dump_wallet(): string;
|
||||
export function reset_process_cache(): void;
|
||||
export function dump_process_cache(): string;
|
||||
export function set_process_cache(processes: any): void;
|
||||
export function add_to_process_cache(process_id: string, process: string): void;
|
||||
export function reset_shared_secrets(): void;
|
||||
export function set_shared_secrets(secrets: string): void;
|
||||
export function get_pairing_process_id(): string;
|
||||
export function dump_device(): Device;
|
||||
export function dump_neutered_device(): Device;
|
||||
export function reset_device(): void;
|
||||
export function get_txid(transaction: string): string;
|
||||
export function parse_new_tx(new_tx_msg: string, block_height: number, members_list: OutPointMemberMap): ApiReturn;
|
||||
export function parse_cipher(cipher_msg: string, members_list: OutPointMemberMap): ApiReturn;
|
||||
export function get_outputs(): any;
|
||||
export function get_available_amount(): bigint;
|
||||
/**
|
||||
* We send a transaction that pays at least one output to each address
|
||||
* The goal can be to establish a shared_secret to be used as an encryption key for further communication
|
||||
* or if the recipient is a relay it can be the init transaction for a new process
|
||||
*/
|
||||
export function create_transaction(addresses: string[], fee_rate: number): ApiReturn;
|
||||
export function sign_transaction(partial_tx: TsUnsignedTransaction): ApiReturn;
|
||||
export function create_new_process(private_data: Pcd, roles: Roles, public_data: Pcd, relay_address: string, fee_rate: number, members_list: OutPointMemberMap): ApiReturn;
|
||||
export function update_process(process: Process, new_attributes: Pcd, roles: Roles, new_public_data: Pcd, members_list: OutPointMemberMap): ApiReturn;
|
||||
export function request_data(process_id: string, state_ids_str: string[], roles: any, members_list: OutPointMemberMap): ApiReturn;
|
||||
export function create_update_message(process: Process, state_id: string, members_list: OutPointMemberMap): ApiReturn;
|
||||
export function validate_state(process: Process, state_id: string, members_list: OutPointMemberMap): ApiReturn;
|
||||
export function refuse_state(process: Process, state_id: string, members_list: OutPointMemberMap): ApiReturn;
|
||||
export function evaluate_state(process: Process, state_id: string, members_list: OutPointMemberMap): ApiReturn;
|
||||
export function create_response_prd(process: Process, state_id: string, members_list: OutPointMemberMap): ApiReturn;
|
||||
export function create_faucet_msg(): string;
|
||||
export function get_storages(process_outpoint: string): string[];
|
||||
export function is_child_role(parent_roles: string, child_roles: string): void;
|
||||
export function decrypt_data(key: Uint8Array, data: Uint8Array): Uint8Array;
|
||||
export function encode_binary(data: any): Pcd;
|
||||
export function encode_json(json_data: any): Pcd;
|
||||
export function decode_value(value: Uint8Array): any;
|
||||
export function hash_value(value: any, commited_in: string, label: string): string;
|
||||
/**
|
||||
* Generate a merkle proof for a specific attribute in a process state.
|
||||
*
|
||||
* This function creates a merkle proof that proves the existence of a specific attribute
|
||||
* in a given state of a process. The proof can be used to verify that the attribute
|
||||
* was indeed part of the state without revealing the entire state.
|
||||
*
|
||||
* # Arguments
|
||||
* * `process_state` - The process state object as a JavaScript value
|
||||
* * `attribute_name` - The name of the attribute to generate a proof for
|
||||
*
|
||||
* # Returns
|
||||
* A MerkleProofResult object containing:
|
||||
* * `proof` - The merkle proof as a hex string
|
||||
* * `root` - The merkle root (state_id) as a hex string
|
||||
* * `attribute` - The attribute name that was proven
|
||||
* * `attribute_index` - The index of the attribute in the merkle tree
|
||||
* * `total_leaves_count` - The total number of leaves in the merkle tree
|
||||
*
|
||||
* # Errors
|
||||
* * "Failed to deserialize process state" - If the process state cannot be deserialized from JsValue
|
||||
* * "Attribute not found in state" - If the attribute doesn't exist in the state
|
||||
*/
|
||||
export function get_merkle_proof(process_state: any, attribute_name: string): MerkleProofResult;
|
||||
/**
|
||||
* Validate a merkle proof for a specific attribute.
|
||||
*
|
||||
* This function verifies that a merkle proof is valid and proves the existence
|
||||
* of a specific attribute in a given state. It checks that the proof correctly
|
||||
* leads to the claimed root when combined with the attribute hash.
|
||||
*
|
||||
* # Arguments
|
||||
* * `proof_result` - a JsValue expected to contain a MerkleProofResult with the proof and metadata
|
||||
* * `hash` - The hash of the attribute data as a hex string (the leaf value)
|
||||
*
|
||||
* # Returns
|
||||
* A boolean indicating whether the proof is valid
|
||||
*
|
||||
* # Errors
|
||||
* * "serde_wasm_bindgen deserialization error" - If the proof is not a valid MerkleProofResult
|
||||
* * "Invalid proof format" - If the proof cannot be parsed
|
||||
* * "Invalid hash format" - If the hash is not a valid 32-byte hex string
|
||||
* * "Invalid root format" - If the root is not a valid 32-byte hex string
|
||||
*/
|
||||
export function validate_merkle_proof(proof_result: any, hash: string): boolean;
|
||||
export type DiffStatus = "None" | "Rejected" | "Validated";
|
||||
|
||||
export interface UserDiff {
|
||||
process_id: string;
|
||||
state_id: string;
|
||||
value_commitment: string;
|
||||
field: string;
|
||||
roles: Roles;
|
||||
description: string | null;
|
||||
notify_user: boolean;
|
||||
need_validation: boolean;
|
||||
validation_status: DiffStatus;
|
||||
}
|
||||
|
||||
export interface UpdatedProcess {
|
||||
process_id: OutPoint;
|
||||
current_process: Process;
|
||||
diffs: UserDiff[];
|
||||
encrypted_data: Record<string, string>;
|
||||
validated_state: number[] | null;
|
||||
}
|
||||
|
||||
export interface ApiReturn {
|
||||
secrets: SecretsStore | null;
|
||||
updated_process: UpdatedProcess | null;
|
||||
new_tx_to_send: NewTxMessage | null;
|
||||
ciphers_to_send: string[];
|
||||
commit_to_send: CommitMessage | null;
|
||||
push_to_storage: string[];
|
||||
partial_tx: TsUnsignedTransaction | null;
|
||||
}
|
||||
|
||||
export interface encryptWithNewKeyResult {
|
||||
cipher: string;
|
||||
key: string;
|
||||
}
|
||||
|
||||
export interface MerkleProofResult {
|
||||
proof: string;
|
||||
root: string;
|
||||
attribute: string;
|
||||
attribute_index: number;
|
||||
total_leaves_count: number;
|
||||
}
|
||||
|
||||
export interface Device {
|
||||
sp_wallet: SpWallet;
|
||||
pairing_process_commitment: OutPoint | null;
|
||||
paired_member: Member;
|
||||
}
|
||||
|
||||
export interface Prd {
|
||||
prd_type: PrdType;
|
||||
process_id: OutPoint;
|
||||
sender: Member;
|
||||
keys: Record<string, number[]>;
|
||||
pcd_commitments: PcdCommitments;
|
||||
validation_tokens: Proof[];
|
||||
roles: Roles;
|
||||
public_data: Pcd;
|
||||
payload: string;
|
||||
proof: Proof | null;
|
||||
}
|
||||
|
||||
export type PrdType = "None" | "Connect" | "Message" | "Update" | "List" | "Response" | "Confirm" | "TxProposal" | "Request";
|
||||
|
||||
/**
|
||||
* Réponse de synchronisation
|
||||
*/
|
||||
export interface SyncResponse {
|
||||
request_id: string;
|
||||
relay_id: string;
|
||||
success: boolean;
|
||||
messages: SyncMessage[];
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requête de synchronisation
|
||||
*/
|
||||
export interface SyncRequest {
|
||||
request_id: string;
|
||||
relay_id: string;
|
||||
sync_types: SyncType[];
|
||||
since_timestamp: number | null;
|
||||
max_items: number | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Capacité d\'un relais
|
||||
*/
|
||||
export interface Capability {
|
||||
name: string;
|
||||
version: string;
|
||||
enabled: boolean;
|
||||
parameters: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connexion mesh entre relais
|
||||
*/
|
||||
export interface MeshConnection {
|
||||
from_relay: string;
|
||||
to_relay: string;
|
||||
latency: number;
|
||||
bandwidth: number;
|
||||
last_heartbeat: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Topologie du réseau
|
||||
*/
|
||||
export interface NetworkTopology {
|
||||
total_relays: number;
|
||||
connected_relays: number;
|
||||
mesh_connections: MeshConnection[];
|
||||
network_diameter: number;
|
||||
avg_latency: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Statut de santé d\'un relais
|
||||
*/
|
||||
export type HealthStatus = "Healthy" | "Warning" | "Critical" | "Offline";
|
||||
|
||||
/**
|
||||
* Informations sur un relais
|
||||
*/
|
||||
export interface RelayInfo {
|
||||
relay_id: string;
|
||||
address: string;
|
||||
sp_address: string;
|
||||
version: string;
|
||||
uptime: number;
|
||||
last_seen: number;
|
||||
capabilities: string[];
|
||||
health_status: HealthStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Informations sur un pair
|
||||
*/
|
||||
export interface PeerInfo {
|
||||
address: string;
|
||||
sp_address: string;
|
||||
connected_since: number;
|
||||
last_activity: number;
|
||||
message_count: number;
|
||||
capabilities: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Contenu des messages de synchronisation
|
||||
*/
|
||||
export type SyncPayload = { StateData: { chain_tip: number; wallet_balance: number; active_processes: number; connected_peers: number } } | { ProcessData: { processes: OutPointProcessMap; last_update: number } } | { MemberData: { members: OutPointMemberMap; last_update: number } } | { TransactionData: { txid: string; height: number | null; confirmed: boolean; sp_outputs: string[] } } | { BlockData: { height: number; hash: string; timestamp: number; tx_count: number } } | { PeerData: { peers: PeerInfo[]; last_seen: number } } | { RelayData: { relays: RelayInfo[]; network_topology: NetworkTopology } } | { HealthData: { uptime: number; memory_usage: number; cpu_usage: number; active_connections: number; last_block_time: number } } | { MetricsData: { messages_processed: number; transactions_broadcast: number; blocks_scanned: number; errors_count: number; avg_response_time: number } } | { ConfigData: { config_hash: string; features: string[]; version: string } } | { CapabilityData: { capabilities: Capability[]; supported_networks: string[] } };
|
||||
|
||||
/**
|
||||
* Types de synchronisation
|
||||
*/
|
||||
export type SyncType = "StateSync" | "ProcessSync" | "MemberSync" | "TxSync" | "BlockSync" | "PeerSync" | "RelaySync" | "HealthSync" | "MetricsSync" | "ConfigSync" | "CapabilitySync";
|
||||
|
||||
/**
|
||||
* Message de synchronisation pour le réseau mesh des relais
|
||||
*/
|
||||
export interface SyncMessage {
|
||||
sync_type: SyncType;
|
||||
relay_id: string;
|
||||
timestamp: number;
|
||||
sequence_number: number;
|
||||
payload: SyncPayload;
|
||||
signature: string | null;
|
||||
}
|
||||
|
||||
export interface HandshakeMessage {
|
||||
sp_address: string;
|
||||
peers_list: OutPointMemberMap;
|
||||
processes_list: OutPointProcessMap;
|
||||
chain_tip: number;
|
||||
}
|
||||
|
||||
export interface NewTxMessage {
|
||||
transaction: string;
|
||||
tweak_data: string | null;
|
||||
error: AnkError | null;
|
||||
}
|
||||
|
||||
export interface FaucetMessage {
|
||||
sp_address: string;
|
||||
commitment: string;
|
||||
error: AnkError | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Message sent to the server to commit some state in a transaction
|
||||
* Client must first send a commit message with empty validation_tokens
|
||||
* Relay will ignore a commit message for an update he\'s not aware of that also bears validation_tokens
|
||||
*/
|
||||
export interface CommitMessage {
|
||||
process_id: OutPoint;
|
||||
pcd_commitment: PcdCommitments;
|
||||
roles: Roles;
|
||||
public_data: Pcd;
|
||||
validation_tokens: Proof[];
|
||||
error: AnkError | null;
|
||||
}
|
||||
|
||||
export type AnkFlag = "NewTx" | "Faucet" | "Cipher" | "Commit" | "Handshake" | "Sync" | "Unknown";
|
||||
|
||||
export type OutPointProcessMap = Record<OutPoint, Process>;
|
||||
|
||||
export type OutPointMemberMap = Record<OutPoint, Member>;
|
||||
|
||||
/**
|
||||
* A process is basically a succession of states
|
||||
* The latest state MUST be an empty state with only the commited_in field set at the last unspent outpoint
|
||||
* Commiting this last empty state in a transaction is called obliterating a process, basically terminating it
|
||||
*/
|
||||
export interface Process {
|
||||
states: ProcessState[];
|
||||
}
|
||||
|
||||
export interface ProcessState {
|
||||
commited_in: OutPoint;
|
||||
pcd_commitment: Record<string, string>;
|
||||
state_id: string;
|
||||
keys: Record<string, string>;
|
||||
validation_tokens: Proof[];
|
||||
public_data: Pcd;
|
||||
roles: Record<string, RoleDefinition>;
|
||||
}
|
||||
|
||||
export type TsUnsignedTransaction = SilentPaymentUnsignedTransaction;
|
||||
|
||||
export interface SecretsStore {
|
||||
shared_secrets: Record<SilentPaymentAddress, AnkSharedSecretHash>;
|
||||
unconfirmed_secrets: AnkSharedSecretHash[];
|
||||
}
|
||||
|
||||
export type Roles = Record<string, RoleDefinition>;
|
||||
|
||||
export interface RoleDefinition {
|
||||
members: OutPoint[];
|
||||
validation_rules: ValidationRule[];
|
||||
storages: string[];
|
||||
}
|
||||
|
||||
export interface ValidationRule {
|
||||
quorum: number;
|
||||
fields: string[];
|
||||
min_sig_member: number;
|
||||
}
|
||||
|
||||
export type PcdCommitments = Record<string, string>;
|
||||
|
||||
export type Pcd = Record<string, number[]>;
|
||||
|
||||
export interface Member {
|
||||
sp_addresses: string[];
|
||||
}
|
||||
|
5
pkg/sdk_client.js
Normal file
5
pkg/sdk_client.js
Normal file
@ -0,0 +1,5 @@
|
||||
import * as wasm from "./sdk_client_bg.wasm";
|
||||
export * from "./sdk_client_bg.js";
|
||||
import { __wbg_set_wasm } from "./sdk_client_bg.js";
|
||||
__wbg_set_wasm(wasm);
|
||||
wasm.__wbindgen_start();
|
1342
pkg/sdk_client_bg.js
Normal file
1342
pkg/sdk_client_bg.js
Normal file
File diff suppressed because it is too large
Load Diff
BIN
pkg/sdk_client_bg.wasm
Normal file
BIN
pkg/sdk_client_bg.wasm
Normal file
Binary file not shown.
69
pkg/sdk_client_bg.wasm.d.ts
vendored
Normal file
69
pkg/sdk_client_bg.wasm.d.ts
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export const memory: WebAssembly.Memory;
|
||||
export const get_address: () => [number, number, number, number];
|
||||
export const get_member: () => [number, number, number];
|
||||
export const restore_device: (a: any) => [number, number];
|
||||
export const create_device_from_sp_wallet: (a: number, b: number) => [number, number, number, number];
|
||||
export const create_new_device: (a: number, b: number, c: number) => [number, number, number, number];
|
||||
export const is_paired: () => [number, number, number];
|
||||
export const pair_device: (a: number, b: number, c: number, d: number) => [number, number];
|
||||
export const unpair_device: () => [number, number];
|
||||
export const dump_wallet: () => [number, number, number, number];
|
||||
export const reset_process_cache: () => [number, number];
|
||||
export const dump_process_cache: () => [number, number, number, number];
|
||||
export const set_process_cache: (a: any) => [number, number];
|
||||
export const add_to_process_cache: (a: number, b: number, c: number, d: number) => [number, number];
|
||||
export const reset_shared_secrets: () => [number, number];
|
||||
export const set_shared_secrets: (a: number, b: number) => [number, number];
|
||||
export const get_pairing_process_id: () => [number, number, number, number];
|
||||
export const dump_device: () => [number, number, number];
|
||||
export const dump_neutered_device: () => [number, number, number];
|
||||
export const reset_device: () => [number, number];
|
||||
export const get_txid: (a: number, b: number) => [number, number, number, number];
|
||||
export const parse_new_tx: (a: number, b: number, c: number, d: any) => [number, number, number];
|
||||
export const parse_cipher: (a: number, b: number, c: any) => [number, number, number];
|
||||
export const get_outputs: () => [number, number, number];
|
||||
export const get_available_amount: () => [bigint, number, number];
|
||||
export const create_transaction: (a: number, b: number, c: number) => [number, number, number];
|
||||
export const sign_transaction: (a: any) => [number, number, number];
|
||||
export const create_new_process: (a: any, b: any, c: any, d: number, e: number, f: number, g: any) => [number, number, number];
|
||||
export const update_process: (a: any, b: any, c: any, d: any, e: any) => [number, number, number];
|
||||
export const request_data: (a: number, b: number, c: number, d: number, e: any, f: any) => [number, number, number];
|
||||
export const create_update_message: (a: any, b: number, c: number, d: any) => [number, number, number];
|
||||
export const validate_state: (a: any, b: number, c: number, d: any) => [number, number, number];
|
||||
export const refuse_state: (a: any, b: number, c: number, d: any) => [number, number, number];
|
||||
export const evaluate_state: (a: any, b: number, c: number, d: any) => [number, number, number];
|
||||
export const create_response_prd: (a: any, b: number, c: number, d: any) => [number, number, number];
|
||||
export const create_faucet_msg: () => [number, number, number, number];
|
||||
export const get_storages: (a: number, b: number) => [number, number, number, number];
|
||||
export const is_child_role: (a: number, b: number, c: number, d: number) => [number, number];
|
||||
export const decrypt_data: (a: number, b: number, c: number, d: number) => [number, number, number, number];
|
||||
export const encode_binary: (a: any) => [number, number, number];
|
||||
export const encode_json: (a: any) => [number, number, number];
|
||||
export const decode_value: (a: number, b: number) => [number, number, number];
|
||||
export const hash_value: (a: any, b: number, c: number, d: number, e: number) => [number, number, number, number];
|
||||
export const get_merkle_proof: (a: any, b: number, c: number) => [number, number, number];
|
||||
export const validate_merkle_proof: (a: any, b: number, c: number) => [number, number, number];
|
||||
export const setup: () => void;
|
||||
export const rust_zstd_wasm_shim_qsort: (a: number, b: number, c: number, d: number) => void;
|
||||
export const rust_zstd_wasm_shim_malloc: (a: number) => number;
|
||||
export const rust_zstd_wasm_shim_memcmp: (a: number, b: number, c: number) => number;
|
||||
export const rust_zstd_wasm_shim_calloc: (a: number, b: number) => number;
|
||||
export const rust_zstd_wasm_shim_free: (a: number) => void;
|
||||
export const rust_zstd_wasm_shim_memcpy: (a: number, b: number, c: number) => number;
|
||||
export const rust_zstd_wasm_shim_memmove: (a: number, b: number, c: number) => number;
|
||||
export const rust_zstd_wasm_shim_memset: (a: number, b: number, c: number) => number;
|
||||
export const rustsecp256k1_v0_9_2_context_create: (a: number) => number;
|
||||
export const rustsecp256k1_v0_9_2_context_destroy: (a: number) => void;
|
||||
export const rustsecp256k1_v0_9_2_default_illegal_callback_fn: (a: number, b: number) => void;
|
||||
export const rustsecp256k1_v0_9_2_default_error_callback_fn: (a: number, b: number) => void;
|
||||
export const __wbindgen_malloc: (a: number, b: number) => number;
|
||||
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
||||
export const __wbindgen_exn_store: (a: number) => void;
|
||||
export const __externref_table_alloc: () => number;
|
||||
export const __wbindgen_export_4: WebAssembly.Table;
|
||||
export const __externref_table_dealloc: (a: number) => void;
|
||||
export const __wbindgen_free: (a: number, b: number, c: number) => void;
|
||||
export const __externref_drop_slice: (a: number, b: number) => void;
|
||||
export const __wbindgen_start: () => void;
|
@ -692,7 +692,7 @@ fn handle_prd_connect(prd: Prd, secret: AnkSharedSecretHash) -> AnyhowResult<Api
|
||||
let secret_hash = AnkMessageHash::from_message(secret.as_byte_array());
|
||||
let mut shared_secrets = lock_shared_secrets()?;
|
||||
if let Some(prev_proof) = prd.validation_tokens.get(0) {
|
||||
// check that the proof is valid
|
||||
// check that the proof is valid
|
||||
prev_proof.verify()?;
|
||||
// Check it's signed with our key
|
||||
let local_address = SilentPaymentAddress::try_from(sp_wallet.get_receiving_address())?;
|
||||
@ -702,7 +702,7 @@ fn handle_prd_connect(prd: Prd, secret: AnkSharedSecretHash) -> AnyhowResult<Api
|
||||
// Check it signs a prd connect that contains the commitment to the shared secret
|
||||
let empty_prd = Prd::new_connect(local_member, secret_hash, None);
|
||||
let msg = AnkMessageHash::from_message(empty_prd.to_string().as_bytes());
|
||||
if *msg.as_byte_array() != prev_proof.get_message() {
|
||||
if *msg.as_byte_array() != prev_proof.get_message() {
|
||||
return Err(anyhow::Error::msg("Previous proof signs another message"));
|
||||
}
|
||||
// Now we can confirm the secret and link it to an address
|
||||
@ -835,8 +835,8 @@ fn handle_prd(
|
||||
|
||||
let validated_state = Some(to_update.state_id);
|
||||
let mut commit_msg = CommitMessage::new(
|
||||
prd.process_id,
|
||||
updated_state.pcd_commitment,
|
||||
prd.process_id,
|
||||
updated_state.pcd_commitment,
|
||||
updated_state.roles,
|
||||
updated_state.public_data,
|
||||
updated_state.validation_tokens,
|
||||
@ -1016,7 +1016,7 @@ pub fn get_available_amount() -> ApiResult<u64> {
|
||||
}
|
||||
|
||||
fn get_shared_secrets_in_transaction(
|
||||
unsigned_transaction: &SilentPaymentUnsignedTransaction,
|
||||
unsigned_transaction: &SilentPaymentUnsignedTransaction,
|
||||
sp_addresses: &[SilentPaymentAddress]
|
||||
) -> anyhow::Result<HashMap<SilentPaymentAddress, AnkSharedSecretHash>> {
|
||||
let mut new_secrets = HashMap::new();
|
||||
@ -1036,8 +1036,8 @@ fn get_shared_secrets_in_transaction(
|
||||
|
||||
fn create_transaction_for_addresses(
|
||||
device: &Device,
|
||||
freezed_utxos: &HashSet<OutPoint>,
|
||||
sp_addresses: &[SilentPaymentAddress],
|
||||
freezed_utxos: &HashSet<OutPoint>,
|
||||
sp_addresses: &[SilentPaymentAddress],
|
||||
fee_rate: FeeRate
|
||||
) -> anyhow::Result<SilentPaymentUnsignedTransaction> {
|
||||
let mut recipients = Vec::with_capacity(sp_addresses.len());
|
||||
@ -1080,7 +1080,7 @@ fn create_transaction_for_addresses(
|
||||
/// We send a transaction that pays at least one output to each address
|
||||
/// The goal can be to establish a shared_secret to be used as an encryption key for further communication
|
||||
/// or if the recipient is a relay it can be the init transaction for a new process
|
||||
pub fn create_transaction(addresses: Vec<String>, fee_rate: u32) -> ApiResult<ApiReturn> {
|
||||
pub fn create_transaction(addresses: Vec<String>, fee_rate: u32) -> ApiResult<ApiReturn> {
|
||||
if addresses.is_empty() {
|
||||
return Err(ApiError::new("No addresses to connect to".to_owned()));
|
||||
}
|
||||
@ -1207,8 +1207,8 @@ pub fn create_new_process(
|
||||
}
|
||||
|
||||
let commit_msg = CommitMessage::new(
|
||||
process_id,
|
||||
pcd_commitment,
|
||||
process_id,
|
||||
pcd_commitment,
|
||||
roles,
|
||||
public_data,
|
||||
vec![],
|
||||
@ -1250,8 +1250,8 @@ pub fn update_process(
|
||||
}
|
||||
|
||||
let mut new_state = ProcessState::new(
|
||||
process.get_process_tip()?,
|
||||
new_attributes.clone(),
|
||||
process.get_process_tip()?,
|
||||
new_attributes.clone(),
|
||||
prev_public_data,
|
||||
roles.clone()
|
||||
)?;
|
||||
@ -1303,8 +1303,8 @@ pub fn update_process(
|
||||
};
|
||||
|
||||
let commit_msg = CommitMessage::new(
|
||||
process_id,
|
||||
new_state.pcd_commitment,
|
||||
process_id,
|
||||
new_state.pcd_commitment,
|
||||
roles,
|
||||
new_state.public_data,
|
||||
vec![]
|
||||
@ -1353,8 +1353,8 @@ pub fn request_data(process_id: String, state_ids_str: Vec<String>, roles: JsVal
|
||||
}
|
||||
|
||||
let prd_request = Prd::new_request(
|
||||
process_id,
|
||||
members_list.0.get(&sender_pairing_id).unwrap().clone(),
|
||||
process_id,
|
||||
members_list.0.get(&sender_pairing_id).unwrap().clone(),
|
||||
state_ids
|
||||
);
|
||||
|
||||
@ -1409,7 +1409,7 @@ pub fn create_update_message(
|
||||
};
|
||||
// Check that we have a shared_secret with all members
|
||||
if let Some(no_secret_address) = member.get_addresses().iter()
|
||||
.find(|a| shared_secrets.get_secret_for_address(a.as_str().try_into().unwrap()).is_none())
|
||||
.find(|a| shared_secrets.get_secret_for_address(a.as_str().try_into().unwrap()).is_none())
|
||||
{
|
||||
// We ignore it if we don't have a secret with ourselves
|
||||
if *no_secret_address != local_address {
|
||||
@ -1485,8 +1485,8 @@ pub fn evaluate_state(process: Process, state_id: String, members_list: OutPoint
|
||||
|
||||
// We create a commit msg with the valid state
|
||||
let commit_msg = CommitMessage::new(
|
||||
process_id,
|
||||
process_state.pcd_commitment.clone(),
|
||||
process_id,
|
||||
process_state.pcd_commitment.clone(),
|
||||
process_state.roles.clone(),
|
||||
process_state.public_data.clone(),
|
||||
vec![]
|
||||
@ -1518,7 +1518,7 @@ fn add_validation_token(mut process: Process, state_id: String, approval: bool,
|
||||
|
||||
let mut commit_msg = CommitMessage::new(
|
||||
process_id,
|
||||
update_state.pcd_commitment.clone(),
|
||||
update_state.pcd_commitment.clone(),
|
||||
update_state.roles.clone(),
|
||||
update_state.public_data.clone(),
|
||||
update_state.validation_tokens.clone()
|
||||
@ -1576,7 +1576,7 @@ fn new_response_prd(process_id: OutPoint, update_state: &ProcessState, members_l
|
||||
};
|
||||
// Check that we have a shared_secret with all members
|
||||
if let Some(no_secret_address) = member.get_addresses().iter()
|
||||
.find(|a| shared_secrets.get_secret_for_address(a.as_str().try_into().unwrap()).is_none())
|
||||
.find(|a| shared_secrets.get_secret_for_address(a.as_str().try_into().unwrap()).is_none())
|
||||
{
|
||||
// We ignore it if we don't have a secret with ourselves
|
||||
if *no_secret_address != local_address {
|
||||
@ -1601,7 +1601,7 @@ fn new_response_prd(process_id: OutPoint, update_state: &ProcessState, members_l
|
||||
let response_prd = Prd::new_response(
|
||||
process_id,
|
||||
sender,
|
||||
vec![*proof],
|
||||
vec![*proof],
|
||||
update_state.pcd_commitment.clone(),
|
||||
);
|
||||
let prd_msg = response_prd.to_network_msg(local_device.get_sp_client())?;
|
||||
@ -1650,7 +1650,7 @@ pub fn create_faucet_msg() -> ApiResult<String> {
|
||||
#[wasm_bindgen]
|
||||
pub fn get_storages(process_outpoint: String) -> ApiResult<Vec<String>> {
|
||||
let outpoint = OutPoint::from_str(&process_outpoint)?;
|
||||
|
||||
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
@ -1753,15 +1753,15 @@ pub struct MerkleProofResult {
|
||||
|
||||
#[wasm_bindgen]
|
||||
/// Generate a merkle proof for a specific attribute in a process state.
|
||||
///
|
||||
///
|
||||
/// This function creates a merkle proof that proves the existence of a specific attribute
|
||||
/// in a given state of a process. The proof can be used to verify that the attribute
|
||||
/// was indeed part of the state without revealing the entire state.
|
||||
///
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `process_state` - The process state object as a JavaScript value
|
||||
/// * `attribute_name` - The name of the attribute to generate a proof for
|
||||
///
|
||||
///
|
||||
/// # Returns
|
||||
/// A MerkleProofResult object containing:
|
||||
/// * `proof` - The merkle proof as a hex string
|
||||
@ -1769,7 +1769,7 @@ pub struct MerkleProofResult {
|
||||
/// * `attribute` - The attribute name that was proven
|
||||
/// * `attribute_index` - The index of the attribute in the merkle tree
|
||||
/// * `total_leaves_count` - The total number of leaves in the merkle tree
|
||||
///
|
||||
///
|
||||
/// # Errors
|
||||
/// * "Failed to deserialize process state" - If the process state cannot be deserialized from JsValue
|
||||
/// * "Attribute not found in state" - If the attribute doesn't exist in the state
|
||||
@ -1777,21 +1777,21 @@ pub fn get_merkle_proof(process_state: JsValue, attribute_name: String) -> ApiRe
|
||||
// Deserialize the process state from JsValue
|
||||
let state: ProcessState = serde_wasm_bindgen::from_value(process_state)
|
||||
.map_err(|_| ApiError::new("Failed to deserialize process state".to_owned()))?;
|
||||
|
||||
|
||||
// Create merkle tree from the PCD commitments
|
||||
let merkle_tree = state.pcd_commitment.create_merkle_tree()?;
|
||||
|
||||
|
||||
// Find the index of the attribute in the commitments
|
||||
let attribute_index = state.pcd_commitment.find_index_of(&attribute_name)
|
||||
.ok_or(ApiError::new("Attribute not found in state".to_owned()))?;
|
||||
|
||||
// Generate the merkle proof for the attribute
|
||||
let proof = merkle_tree.proof(&[attribute_index]);
|
||||
|
||||
|
||||
// Convert the proof to a format that can be serialized to JavaScript
|
||||
let proof_bytes = proof.to_bytes();
|
||||
let proof_hex = proof_bytes.to_lower_hex_string();
|
||||
|
||||
|
||||
Ok(MerkleProofResult {
|
||||
proof: proof_hex,
|
||||
root: state.state_id.to_lower_hex_string(),
|
||||
@ -1803,18 +1803,18 @@ pub fn get_merkle_proof(process_state: JsValue, attribute_name: String) -> ApiRe
|
||||
|
||||
#[wasm_bindgen]
|
||||
/// Validate a merkle proof for a specific attribute.
|
||||
///
|
||||
///
|
||||
/// This function verifies that a merkle proof is valid and proves the existence
|
||||
/// of a specific attribute in a given state. It checks that the proof correctly
|
||||
/// leads to the claimed root when combined with the attribute hash.
|
||||
///
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `proof_result` - a JsValue expected to contain a MerkleProofResult with the proof and metadata
|
||||
/// * `hash` - The hash of the attribute data as a hex string (the leaf value)
|
||||
///
|
||||
///
|
||||
/// # Returns
|
||||
/// A boolean indicating whether the proof is valid
|
||||
///
|
||||
///
|
||||
/// # Errors
|
||||
/// * "serde_wasm_bindgen deserialization error" - If the proof is not a valid MerkleProofResult
|
||||
/// * "Invalid proof format" - If the proof cannot be parsed
|
||||
@ -1825,7 +1825,7 @@ pub fn validate_merkle_proof(proof_result: JsValue, hash: String) -> ApiResult<b
|
||||
let root_bytes: [u8; 32] = Vec::from_hex(&proof_result.root)?
|
||||
.try_into()
|
||||
.map_err(|_| ApiError::new("Invalid root format".to_owned()))?;
|
||||
|
||||
|
||||
let proof_bytes = Vec::from_hex(&proof_result.proof)
|
||||
.map_err(|_| ApiError::new("Invalid proof format".to_owned()))?;
|
||||
|
||||
@ -1834,8 +1834,8 @@ pub fn validate_merkle_proof(proof_result: JsValue, hash: String) -> ApiResult<b
|
||||
|
||||
let hash_bytes: [u8; 32] = Vec::from_hex(&hash)?.try_into()
|
||||
.map_err(|_| ApiError::new("Invalid hash format".to_owned()))?;
|
||||
|
||||
|
||||
let res = verify_merkle_proof(&proof_bytes, &root_bytes, index, &hash_bytes, total_leaves_count)?;
|
||||
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user