@empereur-rouge/pms-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +506 -0
- package/dist/index.cjs +1062 -0
- package/dist/index.d.cts +851 -0
- package/dist/index.d.ts +851 -0
- package/dist/index.js +1028 -0
- package/package.json +71 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,851 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PmsWallet - Wallet pour le réseau PMS.
|
|
3
|
+
*
|
|
4
|
+
* Supporte:
|
|
5
|
+
* - Génération de wallet avec mnémonique 24 mots (BIP39)
|
|
6
|
+
* - Import depuis clé privée
|
|
7
|
+
* - Signature de messages
|
|
8
|
+
* - Export de la phrase mnémonique
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Générer un nouveau wallet
|
|
13
|
+
* const wallet = PmsWallet.generate();
|
|
14
|
+
* console.log(wallet.mnemonic); // 24 mots
|
|
15
|
+
*
|
|
16
|
+
* // Restaurer depuis mnemonic
|
|
17
|
+
* const wallet2 = PmsWallet.fromMnemonic("word1 word2 ...");
|
|
18
|
+
*
|
|
19
|
+
* // Signer un message
|
|
20
|
+
* const sig = await wallet.sign(messageBytes);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Wallet PMS avec gestion des clés cryptographiques.
|
|
25
|
+
*/
|
|
26
|
+
declare class PmsWallet {
|
|
27
|
+
/** Clé privée secp256k1 (32 bytes) - pour signatures */
|
|
28
|
+
private readonly _privateKey;
|
|
29
|
+
/** Clé publique secp256k1 non compressée (65 bytes: 04 + x + y) */
|
|
30
|
+
private readonly _publicKey;
|
|
31
|
+
/** Clé privée X25519 (32 bytes) - pour chiffrement */
|
|
32
|
+
private readonly _x25519PrivateKey;
|
|
33
|
+
/** Clé publique X25519 (32 bytes) */
|
|
34
|
+
private readonly _x25519PublicKey;
|
|
35
|
+
/** Phrase mnémonique (24 mots) si générée/importée */
|
|
36
|
+
private readonly _mnemonic?;
|
|
37
|
+
/**
|
|
38
|
+
* Constructeur privé - utiliser les méthodes statiques.
|
|
39
|
+
*/
|
|
40
|
+
private constructor();
|
|
41
|
+
/**
|
|
42
|
+
* Génère un nouveau wallet avec une phrase de 24 mots.
|
|
43
|
+
*/
|
|
44
|
+
static generate(): PmsWallet;
|
|
45
|
+
/**
|
|
46
|
+
* Crée un wallet à partir d'une phrase mnémonique (12, 15, 18, 21 ou 24 mots).
|
|
47
|
+
* @throws Error si la phrase est invalide
|
|
48
|
+
*/
|
|
49
|
+
static fromMnemonic(mnemonic: string): PmsWallet;
|
|
50
|
+
/**
|
|
51
|
+
* Crée un wallet à partir d'une clé privée hexadécimale.
|
|
52
|
+
*/
|
|
53
|
+
static fromPrivateKey(privateKeyHex: string): PmsWallet;
|
|
54
|
+
/**
|
|
55
|
+
* Crée un wallet à partir d'une seed (32 bytes).
|
|
56
|
+
*/
|
|
57
|
+
static fromSeed(seed: Uint8Array): PmsWallet;
|
|
58
|
+
/**
|
|
59
|
+
* Adresse du wallet (clé publique hex).
|
|
60
|
+
* Format: "04" + 64 bytes hex = 130 caractères
|
|
61
|
+
*/
|
|
62
|
+
get address(): string;
|
|
63
|
+
/**
|
|
64
|
+
* Clé publique en bytes.
|
|
65
|
+
*/
|
|
66
|
+
get publicKey(): Uint8Array;
|
|
67
|
+
/**
|
|
68
|
+
* Clé publique en hex.
|
|
69
|
+
*/
|
|
70
|
+
get publicKeyHex(): string;
|
|
71
|
+
/**
|
|
72
|
+
* Phrase mnémonique (si disponible).
|
|
73
|
+
* @returns undefined si le wallet a été créé depuis une clé privée
|
|
74
|
+
*/
|
|
75
|
+
get mnemonic(): string | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Clé publique X25519 en hex (pour chiffrement).
|
|
78
|
+
* Utiliser cette clé comme destinataire pour encryptPayload().
|
|
79
|
+
*/
|
|
80
|
+
get x25519PublicKeyHex(): string;
|
|
81
|
+
/**
|
|
82
|
+
* Clé privée X25519 en hex (pour déchiffrement).
|
|
83
|
+
* ⚠️ Ne pas exposer cette clé publiquement !
|
|
84
|
+
*/
|
|
85
|
+
get x25519PrivateKeyHex(): string;
|
|
86
|
+
/**
|
|
87
|
+
* Signe un message avec la clé privée.
|
|
88
|
+
* @param message - Message à signer (sera hashé avec SHA256)
|
|
89
|
+
* @returns Signature DER encodée en hex
|
|
90
|
+
*/
|
|
91
|
+
sign(message: Uint8Array): string;
|
|
92
|
+
/**
|
|
93
|
+
* Signe un message déjà hashé.
|
|
94
|
+
* @param hash - Hash 32 bytes du message
|
|
95
|
+
* @returns Signature DER encodée en hex
|
|
96
|
+
*/
|
|
97
|
+
signHash(hash: Uint8Array): string;
|
|
98
|
+
/**
|
|
99
|
+
* Exporte la clé privée en hex.
|
|
100
|
+
* ⚠️ À utiliser avec précaution !
|
|
101
|
+
*/
|
|
102
|
+
exportPrivateKey(): string;
|
|
103
|
+
/**
|
|
104
|
+
* Vérifie une signature.
|
|
105
|
+
* @param message - Message original
|
|
106
|
+
* @param signature - Signature DER hex
|
|
107
|
+
* @param publicKeyHex - Clé publique hex du signataire
|
|
108
|
+
*/
|
|
109
|
+
static verify(message: Uint8Array, signature: string, publicKeyHex: string): boolean;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Vérifie si une phrase mnémonique est valide.
|
|
113
|
+
*/
|
|
114
|
+
declare function isValidMnemonic(mnemonic: string): boolean;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Types TypeScript pour le SDK PMS.
|
|
118
|
+
*
|
|
119
|
+
* Ces types correspondent aux structures de données de l'API REST PMS.
|
|
120
|
+
*/
|
|
121
|
+
/** Référence à un output (UTXO) */
|
|
122
|
+
interface OutputRef {
|
|
123
|
+
/** ID de la transaction */
|
|
124
|
+
txid: string;
|
|
125
|
+
/** Index de l'output dans la transaction */
|
|
126
|
+
index: number;
|
|
127
|
+
}
|
|
128
|
+
/** Output de transaction (UTXO) */
|
|
129
|
+
interface TxOutput {
|
|
130
|
+
/** Adresse du destinataire */
|
|
131
|
+
address: string;
|
|
132
|
+
/** Montant en format décimal (ex: "10.50000000") */
|
|
133
|
+
amount: string;
|
|
134
|
+
/** Asset ID (undefined/null = PMS natif, "edenite" = token custom) */
|
|
135
|
+
asset_id?: string;
|
|
136
|
+
}
|
|
137
|
+
/** UTXO complet avec sa référence */
|
|
138
|
+
interface Utxo extends TxOutput {
|
|
139
|
+
/** Référence à cet UTXO */
|
|
140
|
+
outpoint: OutputRef;
|
|
141
|
+
}
|
|
142
|
+
/** Input de transaction (wrapper autour de OutputRef) */
|
|
143
|
+
interface TxInput {
|
|
144
|
+
/** Référence à l'UTXO dépensé */
|
|
145
|
+
out: OutputRef;
|
|
146
|
+
}
|
|
147
|
+
/** Unlock (signature pour un input) */
|
|
148
|
+
interface Unlock {
|
|
149
|
+
/** Clé publique hex */
|
|
150
|
+
pubkey_hex: string;
|
|
151
|
+
/** Signature base64 */
|
|
152
|
+
signature_b64: string;
|
|
153
|
+
}
|
|
154
|
+
/** Transaction UTXO */
|
|
155
|
+
interface TxUtxo {
|
|
156
|
+
/** Inputs (UTXOs à dépenser) */
|
|
157
|
+
inputs: TxInput[];
|
|
158
|
+
/** Outputs (nouveaux UTXOs) */
|
|
159
|
+
outputs: TxOutput[];
|
|
160
|
+
/** Frais de transaction */
|
|
161
|
+
fee: string;
|
|
162
|
+
/** Unlocks (signatures pour chaque input) */
|
|
163
|
+
unlocks: Unlock[];
|
|
164
|
+
}
|
|
165
|
+
/** Enveloppe de payload */
|
|
166
|
+
type PayloadEnvelope = {
|
|
167
|
+
Plain: PlainPayload;
|
|
168
|
+
} | {
|
|
169
|
+
Encrypted: EncryptedPayload;
|
|
170
|
+
};
|
|
171
|
+
/** Payload en clair */
|
|
172
|
+
type PlainPayload = {
|
|
173
|
+
Mint: MintPayload;
|
|
174
|
+
} | {
|
|
175
|
+
TxUtxo: TxUtxo;
|
|
176
|
+
} | {
|
|
177
|
+
Milestone: MilestonePayload;
|
|
178
|
+
} | {
|
|
179
|
+
Nft: NftAction;
|
|
180
|
+
} | {
|
|
181
|
+
ConfigUpdate: ConfigUpdate;
|
|
182
|
+
} | {
|
|
183
|
+
Reward: RewardPayload;
|
|
184
|
+
} | {
|
|
185
|
+
EncryptedReward: EncryptedRewardPayload;
|
|
186
|
+
} | {
|
|
187
|
+
TokenCreate: TokenMetadata;
|
|
188
|
+
};
|
|
189
|
+
/** Payload de récompense (Mining/Fees) */
|
|
190
|
+
interface RewardPayload {
|
|
191
|
+
fee_outputs: TaggedOutput[];
|
|
192
|
+
reward_outputs: TxOutput[];
|
|
193
|
+
burned: string;
|
|
194
|
+
tx_block_id: string;
|
|
195
|
+
}
|
|
196
|
+
/** Output avec tag (pour fees) */
|
|
197
|
+
interface TaggedOutput extends TxOutput {
|
|
198
|
+
tag: string;
|
|
199
|
+
}
|
|
200
|
+
/** Payload de récompense chiffrée */
|
|
201
|
+
interface EncryptedRewardPayload {
|
|
202
|
+
encrypted_outputs: EncryptedRewardOutput[];
|
|
203
|
+
burned: string;
|
|
204
|
+
tx_block_id: string;
|
|
205
|
+
}
|
|
206
|
+
/** Output de récompensation chiffré individuellement */
|
|
207
|
+
interface EncryptedRewardOutput {
|
|
208
|
+
encrypted: EncryptedPayload;
|
|
209
|
+
}
|
|
210
|
+
/** Payload chiffré - compatible avec pms-types-payload/encrypted_payload.rs */
|
|
211
|
+
interface EncryptedPayload {
|
|
212
|
+
/** Schéma de chiffrement (toujours "x25519+aes256gcm") */
|
|
213
|
+
scheme: string;
|
|
214
|
+
/** Version de la clé (pour rotation future) */
|
|
215
|
+
key_version: number;
|
|
216
|
+
/** Métadonnée authentifiée (taille du payload) */
|
|
217
|
+
aad: {
|
|
218
|
+
len_hint: number;
|
|
219
|
+
};
|
|
220
|
+
/** Hash SHA256 du plaintext pour vérification */
|
|
221
|
+
commitment: string;
|
|
222
|
+
/** Données chiffrées en base64 */
|
|
223
|
+
ciphertext_b64: string;
|
|
224
|
+
/** Liste des destinataires avec leurs clés enveloppées */
|
|
225
|
+
recipients: KeyWrap[];
|
|
226
|
+
/** Nonce AES-GCM en base64 (12 bytes) */
|
|
227
|
+
nonce_b64: string;
|
|
228
|
+
}
|
|
229
|
+
/** Clé enveloppée pour un destinataire */
|
|
230
|
+
interface KeyWrap {
|
|
231
|
+
/** Identifiant opaque du destinataire (dérivé du secret partagé) */
|
|
232
|
+
kid: string;
|
|
233
|
+
/** Clé publique éphémère X25519 (hex) */
|
|
234
|
+
ephem_pub: string;
|
|
235
|
+
/** DEK chiffrée en base64 */
|
|
236
|
+
wrapped_key_b64: string;
|
|
237
|
+
/** Nonce pour le key wrap en base64 */
|
|
238
|
+
kw_nonce_b64: string;
|
|
239
|
+
}
|
|
240
|
+
/** Mint de nouveaux tokens */
|
|
241
|
+
interface MintPayload {
|
|
242
|
+
recipient: string;
|
|
243
|
+
amount: string;
|
|
244
|
+
memo?: string;
|
|
245
|
+
}
|
|
246
|
+
/** Milestone (distribution des récompenses) */
|
|
247
|
+
interface MilestonePayload {
|
|
248
|
+
approved: string[];
|
|
249
|
+
distribute_node_rewards: boolean;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Métadonnées pour un NFT.
|
|
253
|
+
*
|
|
254
|
+
* Ces champs sont tous optionnels pour offrir de la flexibilité,
|
|
255
|
+
* mais au minimum `name` ou `uri` devraient être renseignés.
|
|
256
|
+
*/
|
|
257
|
+
interface NftMetadata {
|
|
258
|
+
/** Nom du NFT (ex: "Mon Artwork #1") */
|
|
259
|
+
name?: string;
|
|
260
|
+
/** Description du NFT */
|
|
261
|
+
description?: string;
|
|
262
|
+
/** URI vers les données/médias du NFT (ex: IPFS CID, URL) */
|
|
263
|
+
uri?: string;
|
|
264
|
+
/** Type de NFT (ex: "art", "collectible", "game_item") */
|
|
265
|
+
nft_type?: string;
|
|
266
|
+
/** Données supplémentaires libres */
|
|
267
|
+
extra?: string;
|
|
268
|
+
}
|
|
269
|
+
/** Actions NFT */
|
|
270
|
+
type NftAction = {
|
|
271
|
+
Mint: {
|
|
272
|
+
token_id: string;
|
|
273
|
+
owner: string;
|
|
274
|
+
metadata: NftMetadata;
|
|
275
|
+
};
|
|
276
|
+
} | {
|
|
277
|
+
Transfer: {
|
|
278
|
+
token_id: string;
|
|
279
|
+
from: string;
|
|
280
|
+
to: string;
|
|
281
|
+
};
|
|
282
|
+
} | {
|
|
283
|
+
Burn: {
|
|
284
|
+
token_id: string;
|
|
285
|
+
burner: string;
|
|
286
|
+
};
|
|
287
|
+
} | {
|
|
288
|
+
BatchBurn: {
|
|
289
|
+
token_ids: string[];
|
|
290
|
+
burner: string;
|
|
291
|
+
};
|
|
292
|
+
} | {
|
|
293
|
+
Use: {
|
|
294
|
+
token_id: string;
|
|
295
|
+
user: string;
|
|
296
|
+
action_type: string;
|
|
297
|
+
};
|
|
298
|
+
};
|
|
299
|
+
/** Métadonnées d'un token enregistré dans le DAG */
|
|
300
|
+
interface TokenMetadata {
|
|
301
|
+
/** Identifiant unique du token (ex: "edenite") */
|
|
302
|
+
asset_id: string;
|
|
303
|
+
/** Symbole court (ex: "EDEN") */
|
|
304
|
+
symbol: string;
|
|
305
|
+
/** Nom complet (ex: "Edenite Token") */
|
|
306
|
+
name: string;
|
|
307
|
+
/** Nombre de décimales (ex: 8) */
|
|
308
|
+
decimals: number;
|
|
309
|
+
/** Supply maximum (undefined = illimité) */
|
|
310
|
+
max_supply?: string;
|
|
311
|
+
/** Adresse du créateur */
|
|
312
|
+
creator: string;
|
|
313
|
+
/** Clé publique autorisée à mint ce token */
|
|
314
|
+
mint_authority: string;
|
|
315
|
+
}
|
|
316
|
+
/** Mise à jour de configuration */
|
|
317
|
+
type ConfigUpdate = {
|
|
318
|
+
SetFeeRate: {
|
|
319
|
+
bps: number;
|
|
320
|
+
};
|
|
321
|
+
} | {
|
|
322
|
+
SetPlatformFee: {
|
|
323
|
+
bps: number;
|
|
324
|
+
};
|
|
325
|
+
} | {
|
|
326
|
+
SetNodeFee: {
|
|
327
|
+
bps: number;
|
|
328
|
+
};
|
|
329
|
+
} | {
|
|
330
|
+
SetMinPow: {
|
|
331
|
+
bits: number;
|
|
332
|
+
};
|
|
333
|
+
} | {
|
|
334
|
+
SetMintEnabled: {
|
|
335
|
+
enabled: boolean;
|
|
336
|
+
};
|
|
337
|
+
};
|
|
338
|
+
/** Bloc du DAG */
|
|
339
|
+
interface Block {
|
|
340
|
+
/** ID unique du bloc (hash) */
|
|
341
|
+
id: string;
|
|
342
|
+
/** IDs des parents */
|
|
343
|
+
parents: string[];
|
|
344
|
+
/** Payload optionnel */
|
|
345
|
+
payload?: PayloadEnvelope;
|
|
346
|
+
/** Nonce PoW */
|
|
347
|
+
nonce: number;
|
|
348
|
+
}
|
|
349
|
+
/** Bloc au format wire (pour soumission) */
|
|
350
|
+
interface WireBlock {
|
|
351
|
+
/** ID du bloc */
|
|
352
|
+
id: string;
|
|
353
|
+
/** Parents */
|
|
354
|
+
parents: string[];
|
|
355
|
+
/** Payload JSON sérialisé */
|
|
356
|
+
payload_json?: string;
|
|
357
|
+
/** Nonce PoW */
|
|
358
|
+
nonce: number;
|
|
359
|
+
/** ID du réseau */
|
|
360
|
+
network_id: string;
|
|
361
|
+
/** Version du protocole */
|
|
362
|
+
protocol_version: number;
|
|
363
|
+
/** Clé publique du signataire (hex) */
|
|
364
|
+
signer_pk_hex: string;
|
|
365
|
+
/** Signature (hex) */
|
|
366
|
+
signature_hex: string;
|
|
367
|
+
}
|
|
368
|
+
/** Informations sur le supply */
|
|
369
|
+
interface SupplyInfo {
|
|
370
|
+
/** Total en circulation */
|
|
371
|
+
circulating: string;
|
|
372
|
+
/** Nombre d'UTXOs */
|
|
373
|
+
utxo_count: number;
|
|
374
|
+
}
|
|
375
|
+
/** Réponse de soumission de bloc */
|
|
376
|
+
interface SubmitResponse {
|
|
377
|
+
/** Statut: "inserted" ou "already_exists" */
|
|
378
|
+
status: "inserted" | "already_exists";
|
|
379
|
+
/** ID du bloc */
|
|
380
|
+
block_id: string;
|
|
381
|
+
}
|
|
382
|
+
/** Attributs générés d'un Cube */
|
|
383
|
+
interface CubeAttributes {
|
|
384
|
+
/** Poids (1-100, hautes valeurs = rares) */
|
|
385
|
+
weight: number;
|
|
386
|
+
/** Taille (1-100, hautes valeurs = rares) */
|
|
387
|
+
size: number;
|
|
388
|
+
/** Densité (1-100, hautes valeurs = rares) */
|
|
389
|
+
density: number;
|
|
390
|
+
}
|
|
391
|
+
/** Réponse de mintCube - inclut les données du cube généré */
|
|
392
|
+
interface MintCubeResponse extends SubmitResponse {
|
|
393
|
+
/** ID unique du cube (64 caractères hex) */
|
|
394
|
+
token_id: string;
|
|
395
|
+
/** Rareté du cube */
|
|
396
|
+
rarity: "Unique" | "Legendary" | "Rare" | "Uncommon" | "Common" | "Basic";
|
|
397
|
+
/** Roll aléatoire utilisé (0-9,999,999) */
|
|
398
|
+
roll: number;
|
|
399
|
+
/** Attributs générés */
|
|
400
|
+
attributes: CubeAttributes;
|
|
401
|
+
}
|
|
402
|
+
/** Preview du remboursement pour un cube brûlé */
|
|
403
|
+
interface RefundPreview {
|
|
404
|
+
/** Montant du remboursement en PMS */
|
|
405
|
+
amount: string;
|
|
406
|
+
/** Adresse destinataire du remboursement */
|
|
407
|
+
recipient: string;
|
|
408
|
+
}
|
|
409
|
+
/** Réponse de burnNft - inclut le refund preview si cube authentique */
|
|
410
|
+
interface BurnNftResponse {
|
|
411
|
+
/** Statut de l'opération ("burned", etc.) */
|
|
412
|
+
status: string;
|
|
413
|
+
/** ID du bloc créé dans le DAG */
|
|
414
|
+
block_id: string;
|
|
415
|
+
/** Token ID du NFT brûlé (ou "batch") */
|
|
416
|
+
token_id: string;
|
|
417
|
+
/** Liste des token IDs brûlés (pour batch burn) */
|
|
418
|
+
token_ids?: string[];
|
|
419
|
+
/** Remboursement (si cube authentique avec signature Authority valide) */
|
|
420
|
+
refund: RefundPreview | null;
|
|
421
|
+
}
|
|
422
|
+
/** Requête pour préparer une transaction de transfert */
|
|
423
|
+
interface PrepareTxRequest {
|
|
424
|
+
/** Adresse Bech32 de l'expéditeur */
|
|
425
|
+
from: string;
|
|
426
|
+
/** Adresse Bech32 du destinataire */
|
|
427
|
+
to: string;
|
|
428
|
+
/** Montant à envoyer (décimal, ex: "100.5") */
|
|
429
|
+
amount: string;
|
|
430
|
+
/** Asset ID (undefined = PMS natif, "edenite" = token custom) */
|
|
431
|
+
asset_id?: string;
|
|
432
|
+
}
|
|
433
|
+
/** Détail d'un UTXO utilisé comme input */
|
|
434
|
+
interface UtxoDetail {
|
|
435
|
+
txid: string;
|
|
436
|
+
index: number;
|
|
437
|
+
amount: string;
|
|
438
|
+
}
|
|
439
|
+
/** Réponse de /v1/tx/prepare - transaction non-signée */
|
|
440
|
+
interface PrepareTxResponse {
|
|
441
|
+
/** Transaction non-signée (unlocks vide) */
|
|
442
|
+
unsigned_tx: TxUtxo;
|
|
443
|
+
/** Hash SHA256 du message à signer (hex) */
|
|
444
|
+
tx_hash: string;
|
|
445
|
+
/** Frais calculés */
|
|
446
|
+
fee: string;
|
|
447
|
+
/** Détail des UTXOs sélectionnés */
|
|
448
|
+
inputs_detail: UtxoDetail[];
|
|
449
|
+
}
|
|
450
|
+
/** Réponse de getNft - informations complètes d'un NFT */
|
|
451
|
+
interface NftResponse {
|
|
452
|
+
/** Token ID du NFT */
|
|
453
|
+
token_id: string;
|
|
454
|
+
/** Propriétaire actuel (null si le token n'existe pas) */
|
|
455
|
+
owner: string | null;
|
|
456
|
+
/** ID du bloc contenant les métadonnées chiffrées (pour récupération + déchiffrement client) */
|
|
457
|
+
mint_block_id: string | null;
|
|
458
|
+
/** Existe-t-il sur le DAG ? */
|
|
459
|
+
exists: boolean;
|
|
460
|
+
/** @deprecated Les métadonnées sont maintenant chiffrées dans le bloc source */
|
|
461
|
+
metadata?: NftMetadata;
|
|
462
|
+
}
|
|
463
|
+
/** Balance d'une adresse */
|
|
464
|
+
interface BalanceInfo {
|
|
465
|
+
/** Adresse */
|
|
466
|
+
address: string;
|
|
467
|
+
/** Balance totale */
|
|
468
|
+
balance: string;
|
|
469
|
+
/** Liste des UTXOs */
|
|
470
|
+
utxos: Utxo[];
|
|
471
|
+
}
|
|
472
|
+
/** Configuration du client PMS */
|
|
473
|
+
interface PmsClientConfig {
|
|
474
|
+
/** URL du nœud principal (ex: "https://node.pms.network") */
|
|
475
|
+
nodeUrl: string;
|
|
476
|
+
/** URLs des noeuds seeds (optionnel, pour racing et fallback) */
|
|
477
|
+
seedNodes?: string[];
|
|
478
|
+
/** ID du réseau (défaut: "pms-mainnet") */
|
|
479
|
+
networkId?: string;
|
|
480
|
+
/** Version du protocole (défaut: 1) */
|
|
481
|
+
protocolVersion?: number;
|
|
482
|
+
/** Timeout en ms (défaut: 30000) */
|
|
483
|
+
timeout?: number;
|
|
484
|
+
/** Activer le mode racing (envoie à tous les noeuds connus) (défaut: true) */
|
|
485
|
+
enableRacing?: boolean;
|
|
486
|
+
}
|
|
487
|
+
/** Réponse de l'endpoint d'information du coordinateur */
|
|
488
|
+
interface CoordinatorInfoResponse {
|
|
489
|
+
/** Ce nœud est-il le Coordinateur ? */
|
|
490
|
+
is_coordinator: boolean;
|
|
491
|
+
/** Clé publique secp256k1 (hex) - pour vérifier les signatures */
|
|
492
|
+
secp256k1_pubkey: string;
|
|
493
|
+
/** Clé publique X25519 (hex) - pour le chiffrement */
|
|
494
|
+
x25519_pubkey: string;
|
|
495
|
+
}
|
|
496
|
+
/** Élément d'historique de wallet */
|
|
497
|
+
interface HistoryItem {
|
|
498
|
+
block_id: string;
|
|
499
|
+
ts_ms: number;
|
|
500
|
+
payload_type: string;
|
|
501
|
+
payload: any;
|
|
502
|
+
}
|
|
503
|
+
/** Réponse de l'historique du wallet */
|
|
504
|
+
interface WalletHistoryResp {
|
|
505
|
+
address: string;
|
|
506
|
+
items: HistoryItem[];
|
|
507
|
+
count: number;
|
|
508
|
+
}
|
|
509
|
+
interface RuntimeConfig {
|
|
510
|
+
fee_rate_bps: number;
|
|
511
|
+
base_fee: string;
|
|
512
|
+
platform_fee_bps: number;
|
|
513
|
+
node_fee_bps: number;
|
|
514
|
+
min_pow_bits: number;
|
|
515
|
+
max_mint_per_block: number;
|
|
516
|
+
mint_enabled: boolean;
|
|
517
|
+
updated_at_block: string;
|
|
518
|
+
updated_at_timestamp: number;
|
|
519
|
+
}
|
|
520
|
+
/** Config publique retournée par /v1/config */
|
|
521
|
+
interface NodePublicConfig extends RuntimeConfig {
|
|
522
|
+
fee_recipient: string;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* PmsClient - Client HTTP pour interagir avec un nœud PMS.
|
|
527
|
+
*
|
|
528
|
+
* @example
|
|
529
|
+
* ```typescript
|
|
530
|
+
* const client = new PmsClient({ nodeUrl: "https://node.pms.network" });
|
|
531
|
+
*
|
|
532
|
+
* // Lecture
|
|
533
|
+
* const tips = await client.getTips();
|
|
534
|
+
* const balance = await client.getBalance("04abc...");
|
|
535
|
+
*
|
|
536
|
+
* // Écriture
|
|
537
|
+
* const result = await client.send({
|
|
538
|
+
* to: "04def...",
|
|
539
|
+
* amount: "10.0",
|
|
540
|
+
* wallet: myWallet,
|
|
541
|
+
* });
|
|
542
|
+
* ```
|
|
543
|
+
*/
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Client pour interagir avec l'API REST d'un nœud PMS.
|
|
547
|
+
*/
|
|
548
|
+
declare class PmsClient {
|
|
549
|
+
private readonly config;
|
|
550
|
+
private knownNodes;
|
|
551
|
+
private lastNodeRefresh;
|
|
552
|
+
private readonly NODE_REFRESH_INTERVAL;
|
|
553
|
+
private configCache;
|
|
554
|
+
private readonly CONFIG_TTL;
|
|
555
|
+
/**
|
|
556
|
+
* Crée un nouveau client PMS.
|
|
557
|
+
* @param config - Configuration du client
|
|
558
|
+
* @param config.nodeUrl - URL du nœud principal
|
|
559
|
+
* @param config.enableRacing - Activer le racing pattern
|
|
560
|
+
* @param config.seedNodes - Liste des nœuds de seed
|
|
561
|
+
*/
|
|
562
|
+
constructor(config: PmsClientConfig);
|
|
563
|
+
/**
|
|
564
|
+
* @internal
|
|
565
|
+
* Ajoute un nœud à la liste des nœuds connus.
|
|
566
|
+
*/
|
|
567
|
+
private addKnownNode;
|
|
568
|
+
/**
|
|
569
|
+
* Récupère les tips actuels du DAG.
|
|
570
|
+
*/
|
|
571
|
+
getTips(): Promise<string[]>;
|
|
572
|
+
/**
|
|
573
|
+
* Récupère les informations publiques du coordinateur (clés).
|
|
574
|
+
*/
|
|
575
|
+
getCoordinatorInfo(): Promise<CoordinatorInfoResponse>;
|
|
576
|
+
/**
|
|
577
|
+
* Récupère un bloc par son ID.
|
|
578
|
+
*/
|
|
579
|
+
getBlock(blockId: string): Promise<Block>;
|
|
580
|
+
/**
|
|
581
|
+
* Récupère les informations de supply.
|
|
582
|
+
* @param assetId - Optionnel: ID du token (undefined = PMS natif)
|
|
583
|
+
*/
|
|
584
|
+
getSupply(assetId?: string): Promise<SupplyInfo>;
|
|
585
|
+
/**
|
|
586
|
+
* Liste tous les tokens enregistrés.
|
|
587
|
+
*/
|
|
588
|
+
listTokens(): Promise<TokenMetadata[]>;
|
|
589
|
+
/**
|
|
590
|
+
* Récupère les métadonnées d'un token par son asset_id.
|
|
591
|
+
*/
|
|
592
|
+
getToken(assetId: string): Promise<TokenMetadata>;
|
|
593
|
+
/**
|
|
594
|
+
* Récupère les UTXOs d'une adresse.
|
|
595
|
+
*/
|
|
596
|
+
getUtxos(address: string): Promise<Utxo[]>;
|
|
597
|
+
/**
|
|
598
|
+
* Prépare une transaction de transfert via le serveur.
|
|
599
|
+
* Le serveur sélectionne les UTXOs et calcule les frais.
|
|
600
|
+
* Le client doit ensuite signer le `tx_hash` retourné.
|
|
601
|
+
*
|
|
602
|
+
* @param params - Paramètres de la transaction
|
|
603
|
+
* @param params.from - Adresse Bech32 de l'expéditeur
|
|
604
|
+
* @param params.to - Adresse Bech32 du destinataire
|
|
605
|
+
* @param params.amount - Montant à envoyer (décimal, ex: "100.5")
|
|
606
|
+
* @returns Transaction non-signée avec hash à signer
|
|
607
|
+
*
|
|
608
|
+
* @example
|
|
609
|
+
* ```typescript
|
|
610
|
+
* // 1. Préparer la transaction
|
|
611
|
+
* const prepared = await client.prepareTx({
|
|
612
|
+
* from: wallet.address,
|
|
613
|
+
* to: "pms1recipient...",
|
|
614
|
+
* amount: "100.0"
|
|
615
|
+
* });
|
|
616
|
+
*
|
|
617
|
+
* // 2. Signer le hash
|
|
618
|
+
* const signature = wallet.sign(fromHex(prepared.tx_hash));
|
|
619
|
+
*
|
|
620
|
+
* // 3. Soumettre via /wallet/tx/send (à implémenter)
|
|
621
|
+
* ```
|
|
622
|
+
*/
|
|
623
|
+
prepareTx(params: PrepareTxRequest): Promise<PrepareTxResponse>;
|
|
624
|
+
/**
|
|
625
|
+
* Récupère la balance d'une adresse.
|
|
626
|
+
*/
|
|
627
|
+
/**
|
|
628
|
+
* Récupère la balance d'une adresse.
|
|
629
|
+
*/
|
|
630
|
+
getBalance(address: string): Promise<string>;
|
|
631
|
+
/**
|
|
632
|
+
* Récupère la balance complète avec les UTXOs.
|
|
633
|
+
*/
|
|
634
|
+
getBalanceInfo(address: string): Promise<BalanceInfo>;
|
|
635
|
+
/**
|
|
636
|
+
* Récupère la liste des NFTs appartenant à une adresse.
|
|
637
|
+
*
|
|
638
|
+
* @param address - Adresse publique (hex) du propriétaire
|
|
639
|
+
* @returns Liste des token_ids possédés par cette adresse
|
|
640
|
+
*
|
|
641
|
+
* @example
|
|
642
|
+
* ```typescript
|
|
643
|
+
* const myNfts = await client.getNfts(myWallet.address);
|
|
644
|
+
* console.log(`Vous possédez ${myNfts.length} NFT(s)`);
|
|
645
|
+
* for (const tokenId of myNfts) {
|
|
646
|
+
* console.log(`- ${tokenId}`);
|
|
647
|
+
* }
|
|
648
|
+
* ```
|
|
649
|
+
*/
|
|
650
|
+
getNfts(address: string): Promise<string[]>;
|
|
651
|
+
/**
|
|
652
|
+
* Récupère les informations complètes d'un NFT par son token_id.
|
|
653
|
+
*
|
|
654
|
+
* @param tokenId - Identifiant unique du NFT (64 caractères hex)
|
|
655
|
+
* @returns NftResponse avec owner, exists et metadata
|
|
656
|
+
*
|
|
657
|
+
* @example
|
|
658
|
+
* ```typescript
|
|
659
|
+
* const nft = await client.getNft("abc123def456...");
|
|
660
|
+
* if (nft.exists) {
|
|
661
|
+
* console.log(`Owner: ${nft.owner}`);
|
|
662
|
+
* console.log(`Name: ${nft.metadata?.name}`);
|
|
663
|
+
* }
|
|
664
|
+
* ```
|
|
665
|
+
*/
|
|
666
|
+
getNft(tokenId: string): Promise<NftResponse>;
|
|
667
|
+
/**
|
|
668
|
+
* Récupère l'historique des transactions d'un wallet.
|
|
669
|
+
* Supporte le déchiffrement des récompenses (EncryptedReward) côté client.
|
|
670
|
+
*
|
|
671
|
+
* @param address - Adresse du wallet (bech32)
|
|
672
|
+
* @param options - Options (limit, decryptionWallet)
|
|
673
|
+
* @returns Historique complet
|
|
674
|
+
*/
|
|
675
|
+
getHistory(address: string, options?: {
|
|
676
|
+
limit?: number;
|
|
677
|
+
decryptionWallet?: PmsWallet;
|
|
678
|
+
}): Promise<WalletHistoryResp>;
|
|
679
|
+
/**
|
|
680
|
+
* Récupère la configuration publique du nœud (frais, PoW, recipient, etc.)
|
|
681
|
+
*/
|
|
682
|
+
getNetworkConfig(): Promise<NodePublicConfig>;
|
|
683
|
+
/**
|
|
684
|
+
* Récupère la configuration runtime du nœud (frais, PoW, etc.)
|
|
685
|
+
* @deprecated Use getNetworkConfig instead
|
|
686
|
+
*/
|
|
687
|
+
getRuntimeConfig(): Promise<RuntimeConfig>;
|
|
688
|
+
/**
|
|
689
|
+
* @internal
|
|
690
|
+
* Soumet un bloc au réseau.
|
|
691
|
+
* Utilise le racing pattern si activé pour envoyer à plusieurs noeuds.
|
|
692
|
+
*
|
|
693
|
+
* ⚠️ API interne - préférez utiliser `send()`, `mintNft()`, ou `burnNft()`.
|
|
694
|
+
*/
|
|
695
|
+
submitBlock(wireBlock: WireBlock): Promise<SubmitResponse>;
|
|
696
|
+
/**
|
|
697
|
+
* Discovery & Racing Pattern:
|
|
698
|
+
* 1. Refresh node list if stale
|
|
699
|
+
* 2. Send to all known nodes in parallel
|
|
700
|
+
* 3. Return first success
|
|
701
|
+
*/
|
|
702
|
+
private submitBlockRacing;
|
|
703
|
+
/**
|
|
704
|
+
* Rafraîchit la liste des noeuds connus depuis le registre
|
|
705
|
+
*/
|
|
706
|
+
private refreshNodeList;
|
|
707
|
+
/**
|
|
708
|
+
* Envoie des tokens à une adresse.
|
|
709
|
+
* Construit automatiquement la transaction, la signe et la soumet.
|
|
710
|
+
*/
|
|
711
|
+
send(params: {
|
|
712
|
+
to: string;
|
|
713
|
+
amount: string;
|
|
714
|
+
wallet: PmsWallet;
|
|
715
|
+
memo?: string;
|
|
716
|
+
}): Promise<SubmitResponse>;
|
|
717
|
+
/**
|
|
718
|
+
* Transférer un NFT à un autre propriétaire.
|
|
719
|
+
* Prend en charge le re-chiffrement des métadonnées via le coordinateur.
|
|
720
|
+
*
|
|
721
|
+
* @param params - Paramètres du transfert
|
|
722
|
+
* @param params.tokenId - Identifiant du NFT
|
|
723
|
+
* @param params.to - Adresse du nouveau propriétaire
|
|
724
|
+
* @param params.wallet - Wallet du propriétaire actuel (signataire)
|
|
725
|
+
* @param params.newOwnerX25519 - Clé publique X25519 du nouveau owner (pour re-encryption)
|
|
726
|
+
*/
|
|
727
|
+
transferNft(params: {
|
|
728
|
+
tokenId: string;
|
|
729
|
+
to: string;
|
|
730
|
+
wallet: PmsWallet;
|
|
731
|
+
newOwnerX25519?: string;
|
|
732
|
+
}): Promise<SubmitResponse>;
|
|
733
|
+
/**
|
|
734
|
+
* Brûle (détruit) un NFT existant.
|
|
735
|
+
*
|
|
736
|
+
* Seul le propriétaire du NFT peut le brûler.
|
|
737
|
+
* Une fois brûlé, le NFT est supprimé définitivement.
|
|
738
|
+
*
|
|
739
|
+
* Pour les Cubes authentiques (avec signature Authority valide),
|
|
740
|
+
* un remboursement est calculé selon la formule:
|
|
741
|
+
* `(weight * size * density) / 10000` PMS
|
|
742
|
+
*
|
|
743
|
+
* @param params - Paramètres du burn
|
|
744
|
+
* @param params.tokenId - Identifiant du NFT à brûler
|
|
745
|
+
* @param params.wallet - Wallet PMS du propriétaire (doit être l'owner actuel)
|
|
746
|
+
* @returns BurnNftResponse avec refund preview si cube authentique
|
|
747
|
+
*
|
|
748
|
+
* @example
|
|
749
|
+
* ```typescript
|
|
750
|
+
* const result = await client.burnNft({
|
|
751
|
+
* tokenId: "abc123def456...",
|
|
752
|
+
* wallet: myWallet,
|
|
753
|
+
* });
|
|
754
|
+
*
|
|
755
|
+
* if (result.refund) {
|
|
756
|
+
* console.log(`Remboursement: ${result.refund.amount} PMS`);
|
|
757
|
+
* }
|
|
758
|
+
* ```
|
|
759
|
+
*/
|
|
760
|
+
burnNft(params: {
|
|
761
|
+
tokenId: string;
|
|
762
|
+
wallet: PmsWallet;
|
|
763
|
+
}): Promise<BurnNftResponse>;
|
|
764
|
+
/**
|
|
765
|
+
* Brûle (détruit) plusieurs NFTs en une seule transaction.
|
|
766
|
+
*
|
|
767
|
+
* @param params - Paramètres du batch burn
|
|
768
|
+
* @param params.tokenIds - Liste des Identifiants des NFTs à brûler
|
|
769
|
+
* @param params.wallet - Wallet PMS du propriétaire
|
|
770
|
+
* @returns BurnNftResponse avec refund preview cumulé si applicable
|
|
771
|
+
*/
|
|
772
|
+
burnNfts(params: {
|
|
773
|
+
tokenIds: string[];
|
|
774
|
+
wallet: PmsWallet;
|
|
775
|
+
}): Promise<BurnNftResponse>;
|
|
776
|
+
/**
|
|
777
|
+
* Mint un NFT via le Coordinateur (Server-Side Signing).
|
|
778
|
+
* Le client génère l'ID et les métadonnées, mais c'est le serveur qui signe et chiffre.
|
|
779
|
+
*/
|
|
780
|
+
mintNft(params: {
|
|
781
|
+
wallet: PmsWallet;
|
|
782
|
+
metadata: NftMetadata;
|
|
783
|
+
tokenId?: string;
|
|
784
|
+
}): Promise<SubmitResponse & {
|
|
785
|
+
token_id: string;
|
|
786
|
+
}>;
|
|
787
|
+
/**
|
|
788
|
+
* Mint un Cube avec des attributs générés et signés par le backend Authority.
|
|
789
|
+
* @param params.wallet - Wallet PMS du propriétaire
|
|
790
|
+
* @param params.generatorUrl - URL du backend générateur de cubes (ex: "http://localhost:3000")
|
|
791
|
+
*/
|
|
792
|
+
mintCube(params: {
|
|
793
|
+
wallet: PmsWallet;
|
|
794
|
+
generatorUrl: string;
|
|
795
|
+
}): Promise<MintCubeResponse>;
|
|
796
|
+
/**
|
|
797
|
+
* Génère une chaîne hexadécimale aléatoire de la longueur spécifiée (en bytes).
|
|
798
|
+
* Utilise crypto.getRandomValues pour la sécurité cryptographique.
|
|
799
|
+
*/
|
|
800
|
+
private generateRandomHex;
|
|
801
|
+
private fetch;
|
|
802
|
+
private fetchUrl;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* Convertit des bytes en hex.
|
|
807
|
+
*/
|
|
808
|
+
declare function toHex(bytes: Uint8Array): string;
|
|
809
|
+
/**
|
|
810
|
+
* Convertit un hex en bytes.
|
|
811
|
+
*/
|
|
812
|
+
declare function fromHex(hex: string): Uint8Array;
|
|
813
|
+
/**
|
|
814
|
+
* Parse un montant décimal en satoshis (8 décimales).
|
|
815
|
+
*/
|
|
816
|
+
declare function parseAmount(amount: string): bigint;
|
|
817
|
+
/**
|
|
818
|
+
* Formate des satoshis en montant décimal.
|
|
819
|
+
*/
|
|
820
|
+
declare function formatAmount(sats: bigint): string;
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Fonctions de chiffrement pour le SDK PMS.
|
|
824
|
+
*
|
|
825
|
+
* Compatible avec le backend Rust (pms-types-payload/encrypted_payload.rs).
|
|
826
|
+
* Schéma: X25519 + AES-256-GCM avec key wrapping multi-destinataires.
|
|
827
|
+
*
|
|
828
|
+
* CONCEPTS CLÉS (pour débutants Rust, applicable ici aussi):
|
|
829
|
+
* - DEK (Data Encryption Key): Clé symétrique pour chiffrer les données
|
|
830
|
+
* - KEK (Key Encryption Key): Clé pour "envelopper" la DEK
|
|
831
|
+
* - ECDH: Échange de clé Diffie-Hellman sur courbe elliptique
|
|
832
|
+
* - HKDF: Fonction de dérivation de clé à partir d'un secret partagé
|
|
833
|
+
*/
|
|
834
|
+
|
|
835
|
+
/**
|
|
836
|
+
* Déchiffre un payload chiffré avec la clé privée X25519 du destinataire.
|
|
837
|
+
*
|
|
838
|
+
* @param encrypted - Payload chiffré (output de encryptPayload)
|
|
839
|
+
* @param recipientPrivateKeyHex - Clé privée X25519 du destinataire (64 chars hex)
|
|
840
|
+
* @returns Les données en clair (string)
|
|
841
|
+
* @throws Error si le déchiffrement échoue
|
|
842
|
+
*
|
|
843
|
+
* @example
|
|
844
|
+
* ```typescript
|
|
845
|
+
* const plaintext = decryptPayload(encrypted, myX25519PrivateKeyHex);
|
|
846
|
+
* const data = JSON.parse(plaintext);
|
|
847
|
+
* ```
|
|
848
|
+
*/
|
|
849
|
+
declare function decryptPayload(encrypted: EncryptedPayload, recipientPrivateKeyHex: string): string;
|
|
850
|
+
|
|
851
|
+
export { type BalanceInfo, type Block, type BurnNftResponse, type CoordinatorInfoResponse, type CubeAttributes, type HistoryItem, type MintCubeResponse, type NftMetadata, type NftResponse, PmsClient, type PmsClientConfig, PmsWallet, type PrepareTxRequest, type PrepareTxResponse, type RuntimeConfig, type SubmitResponse, type SupplyInfo, type TokenMetadata, type Utxo, type UtxoDetail, type WalletHistoryResp, decryptPayload, formatAmount, fromHex, isValidMnemonic, parseAmount, toHex };
|