4NK_env/docs/SDK_USAGE_SPEC.md

6.5 KiB
Raw Permalink Blame History

Spécifications d'utilisation: sdk_common, sdk_relay, rust-silentpayments

Ce document décrit comment utiliser les briques 4NK côté client pour: (1) les types/utilitaires communs, (2) l'intégration au relay (WebSocket), et (3) l'usage de la librairie Rust « silent payments » exposée via wasm (pkg/sdk_client.js).

1) sdk_common (contrats et conventions)

  • Rôle: référentiel de types/constantes (MessageType, enveloppe de messages, erreurs), helpers purs. Dans ce projet, il n'est pas modifié par les specs chat; l'hôte/iframe se basent sur MessageType existants et un CHANNEL_MESSAGE côté IHM.
  • Enveloppes: { type, messageId, correlationId?, payload, ts?, version? }
  • Erreurs: ERROR { code, reason, details?, refMessageId? }
  • Bonnes pratiques: versionner la sémantique applicative via version dans payload si nécessaire (ex: chat/1.0).

2) sdk_relay (intégration relay via WebSocket)

  • Transport: WebSocket vers VITE_BOOTSTRAPURL (fallback wss://${BASEURL}/ws/).
  • Fichier de référence: 4NK_modules/ihm_client/src/websockets.ts et src/services/service.ts.
  • Canaux applicatifs (flags): NewTx, Commit, Cipher, Faucet (utilisés par Services.send*Message).

Interfaces (côté host/IHM)

// Initialisation de la connexion
await initWebsocket('wss://<relay>/ws/');

// Envoi générique (wrappé par Services)
sendMessage(flag: 'NewTx'|'Commit'|'Cipher'|'Faucet', message: string): void

// Événements
ws.onopen: flush de la file; onmessage: routage vers Services (parse, handleApiReturn)

Handshake et messages relay

  • Services.connectAllRelays() ouvre les WS et attend au moins un « handshake » (waitForHandshakeMessage).
  • Sur message handshake: handleHandshakeMsg(url, parsed) met à jour:
    • relayAddresses[wsurl] -> sp_address
    • membersList (peers)
    • processesCache (via batchSaveProcessesToDb ou merge par state)
    • déclenche checkConnections et request_data si des clés manquent

Séquences typiques (texte)

  1. Démarrage: connectAllRelayswaitForHandshakeMessagemembersList/processes prêts.
  2. Parse de nouveaux TX: parse_new_txhandleApiReturn → envoi NewTx et MAJ device.
  3. Partage de secrets/données: request_data(processId, stateIds, roles, members)handleApiReturn alimente secrets/IndexedDB.

3) rust-silentpayments (wasm sdk_client)

  • Exposé via 4NK_modules/ihm_client/pkg/sdk_client.js.
  • Fonctions principales utilisées:
    • Device: create_new_device, restore_device, dump_device, dump_neutered_device, get_available_amount, get_address, scan_blocks, reset_device.
    • Process: create_new_process, update_process, process_commit_new_state.
    • Cryptographie: encode_json, encode_binary, decode_value, decrypt_data, hash_value.
    • Réseau/process sync: create_transaction (connexion membres), create_update_message, create_response_prd, validate_state, refuse_state, parse_cipher, parse_new_tx, request_data, sign_transaction.

Interfaces (signatures conceptuelles)

// Création d'un device et restauration
create_new_device(birthday: number, network: 'signet'|'testnet'|'mainnet'): string // retourne sp_address
restore_device(device: Device): void
dump_device(): Device
get_pairing_process_id(): string

// Encodage/chiffrement
encode_json(obj: Record<string, any>): Record<string, number[]>
encode_binary(files: Record<string, { type: string; data: Uint8Array }>): Record<string, number[]>
decode_value(encoded: number[]): any
decrypt_data(key: Uint8Array, cipher: Uint8Array): number[] // puis decode_value(clear)

// Process
create_new_process(encodedPrivate, roles, encodedPublic, relayAddress, feeRate, members): ApiReturn
update_process(process, encodedPrivate, rolesOrNull, encodedPublic, members): ApiReturn
validate_state(process, stateId, members): ApiReturn
create_update_message(process, stateId, members): ApiReturn
create_response_prd(process, stateId, members): ApiReturn
refuse_state(process, stateId): ApiReturn

// Réseau/sync
create_transaction(addresses: string[], feeRate: number): ApiReturn
request_data(processId: string, stateIds: string[], roles: RoleDefinition[], members): ApiReturn
parse_cipher(message: string, members, processes): ApiReturn
parse_new_tx(newTxMsg: string, _: number, members): ApiReturn
sign_transaction(partial): { new_tx_to_send: NewTxMessage }

Pseudocode réaliste

Création dun process

const { jsonCompatibleData, binaryData } = splitData(privateData);
const encodedPrivate = { ...sdk.encode_json(jsonCompatibleData), ...sdk.encode_binary(binaryData) };
const encodedPublic = { ...sdk.encode_json(publicData) };
const members = services.getAllMembers();
const res = sdk.create_new_process(encodedPrivate, roles, encodedPublic, relayAddr, 1, members);
await services.handleApiReturn(res); // stocke process, blobs, secrets, diffs
await services.checkConnections(res.updated_process.current_process);

Mise à jour dun process

const { privateDelta, publicDelta, rolesDelta } = computeDelta(...);
const encPriv = encode(privateDelta);
const encPub = encode(publicDelta);
const res = sdk.update_process(process, encPriv, rolesDelta ?? services.getRoles(process), encPub, services.getAllMembers());
await services.handleApiReturn(res);

Récupération des données privées dun état

// hôte → iframe via postMessage: RETRIEVE_DATA
postMessage({ type: 'RETRIEVE_DATA', processId, stateId, accessToken });

// iframe (router) → Services
const process = await services.getProcess(processId);
await services.checkConnections(process, stateId);
const clear = await services.decryptAttribute(processId, state, 'attributeName');
// réponse: DATA_RETRIEVED

Connexion aux membres (pour obtenir des clés)

await services.ensureSufficientAmount();
const api = sdk.create_transaction(addresses, 1);
await services.handleApiReturn(api); // secrets dans IndexedDB puis set_shared_secrets() via restoreSecretsFromDB

Endpoints / Interfaces réseau

  • WebSocket relay (exemples):
    • URL: wss://<BASEURL>/ws/
    • Messages sortants (JSON): { flag: 'NewTx'|'Commit'|'Cipher'|'Faucet', payload: string }
    • Messages entrants: handshake (contient sp_address, chain_tip, peers_list, processes_list), new_tx, cipher, réponses aux commits/requests.

Bonnes pratiques

  • Toujours attendre au moins un handshake relay avant de tenter request_data.
  • Utiliser handleApiReturn pour appliquer systématiquement les effets (stockage blobs/diffs/process, envoi tx, secrets).
  • Vérifier rôles et pairing avant toute tentative daccès aux privés.