@bitshard.io/bitshard-sdk 0.0.1

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.
Files changed (117) hide show
  1. package/dist/BitShardSDK.d.ts +156 -0
  2. package/dist/BitShardSDK.d.ts.map +1 -0
  3. package/dist/BitShardSDK.js +350 -0
  4. package/dist/BitShardSDK.js.map +1 -0
  5. package/dist/chains/bitcoin/BitcoinChain.d.ts +6 -0
  6. package/dist/chains/bitcoin/BitcoinChain.d.ts.map +1 -0
  7. package/dist/chains/bitcoin/BitcoinChain.js +10 -0
  8. package/dist/chains/bitcoin/BitcoinChain.js.map +1 -0
  9. package/dist/chains/config.d.ts +5 -0
  10. package/dist/chains/config.d.ts.map +1 -0
  11. package/dist/chains/config.js +7 -0
  12. package/dist/chains/config.js.map +1 -0
  13. package/dist/chains/evm/EVMChain.d.ts +6 -0
  14. package/dist/chains/evm/EVMChain.d.ts.map +1 -0
  15. package/dist/chains/evm/EVMChain.js +10 -0
  16. package/dist/chains/evm/EVMChain.js.map +1 -0
  17. package/dist/core/DKLSParty.d.ts +132 -0
  18. package/dist/core/DKLSParty.d.ts.map +1 -0
  19. package/dist/core/DKLSParty.js +267 -0
  20. package/dist/core/DKLSParty.js.map +1 -0
  21. package/dist/core/DKLSService.d.ts +83 -0
  22. package/dist/core/DKLSService.d.ts.map +1 -0
  23. package/dist/core/DKLSService.js +325 -0
  24. package/dist/core/DKLSService.js.map +1 -0
  25. package/dist/core/ThresholdConfig.d.ts +76 -0
  26. package/dist/core/ThresholdConfig.d.ts.map +1 -0
  27. package/dist/core/ThresholdConfig.js +127 -0
  28. package/dist/core/ThresholdConfig.js.map +1 -0
  29. package/dist/core/types.d.ts +238 -0
  30. package/dist/core/types.d.ts.map +1 -0
  31. package/dist/core/types.js +3 -0
  32. package/dist/core/types.js.map +1 -0
  33. package/dist/crypto/addresses.d.ts +82 -0
  34. package/dist/crypto/addresses.d.ts.map +1 -0
  35. package/dist/crypto/addresses.js +242 -0
  36. package/dist/crypto/addresses.js.map +1 -0
  37. package/dist/crypto/elliptic.d.ts +19 -0
  38. package/dist/crypto/elliptic.d.ts.map +1 -0
  39. package/dist/crypto/elliptic.js +114 -0
  40. package/dist/crypto/elliptic.js.map +1 -0
  41. package/dist/crypto/encoding.d.ts +111 -0
  42. package/dist/crypto/encoding.d.ts.map +1 -0
  43. package/dist/crypto/encoding.js +224 -0
  44. package/dist/crypto/encoding.js.map +1 -0
  45. package/dist/index.d.ts +23 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +58 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/protocols/keygen.d.ts +6 -0
  50. package/dist/protocols/keygen.d.ts.map +1 -0
  51. package/dist/protocols/keygen.js +12 -0
  52. package/dist/protocols/keygen.js.map +1 -0
  53. package/dist/protocols/presignature.d.ts +68 -0
  54. package/dist/protocols/presignature.d.ts.map +1 -0
  55. package/dist/protocols/presignature.js +147 -0
  56. package/dist/protocols/presignature.js.map +1 -0
  57. package/dist/protocols/refresh.d.ts +5 -0
  58. package/dist/protocols/refresh.d.ts.map +1 -0
  59. package/dist/protocols/refresh.js +10 -0
  60. package/dist/protocols/refresh.js.map +1 -0
  61. package/dist/protocols/signing.d.ts +7 -0
  62. package/dist/protocols/signing.d.ts.map +1 -0
  63. package/dist/protocols/signing.js +12 -0
  64. package/dist/protocols/signing.js.map +1 -0
  65. package/dist/rpc/RPCProvider.d.ts +6 -0
  66. package/dist/rpc/RPCProvider.d.ts.map +1 -0
  67. package/dist/rpc/RPCProvider.js +6 -0
  68. package/dist/rpc/RPCProvider.js.map +1 -0
  69. package/dist/rpc/methods.d.ts +5 -0
  70. package/dist/rpc/methods.d.ts.map +1 -0
  71. package/dist/rpc/methods.js +10 -0
  72. package/dist/rpc/methods.js.map +1 -0
  73. package/dist/websocket/coordinator.d.ts +6 -0
  74. package/dist/websocket/coordinator.d.ts.map +1 -0
  75. package/dist/websocket/coordinator.js +10 -0
  76. package/dist/websocket/coordinator.js.map +1 -0
  77. package/dist/websocket/messages.d.ts +9 -0
  78. package/dist/websocket/messages.d.ts.map +1 -0
  79. package/dist/websocket/messages.js +7 -0
  80. package/dist/websocket/messages.js.map +1 -0
  81. package/dist/websocket/session.d.ts +5 -0
  82. package/dist/websocket/session.d.ts.map +1 -0
  83. package/dist/websocket/session.js +7 -0
  84. package/dist/websocket/session.js.map +1 -0
  85. package/dist/wire/format.d.ts +8 -0
  86. package/dist/wire/format.d.ts.map +1 -0
  87. package/dist/wire/format.js +11 -0
  88. package/dist/wire/format.js.map +1 -0
  89. package/dist/wire/validation.d.ts +6 -0
  90. package/dist/wire/validation.d.ts.map +1 -0
  91. package/dist/wire/validation.js +13 -0
  92. package/dist/wire/validation.js.map +1 -0
  93. package/package.json +67 -0
  94. package/src/BitShardSDK.ts +428 -0
  95. package/src/chains/bitcoin/BitcoinChain.ts +7 -0
  96. package/src/chains/config.ts +7 -0
  97. package/src/chains/evm/EVMChain.ts +7 -0
  98. package/src/core/DKLSParty.ts +317 -0
  99. package/src/core/DKLSService.ts +426 -0
  100. package/src/core/ThresholdConfig.ts +159 -0
  101. package/src/core/types.ts +253 -0
  102. package/src/crypto/addresses.ts +282 -0
  103. package/src/crypto/elliptic.ts +133 -0
  104. package/src/crypto/encoding.ts +227 -0
  105. package/src/index.ts +40 -0
  106. package/src/protocols/keygen.ts +8 -0
  107. package/src/protocols/presignature.ts +196 -0
  108. package/src/protocols/refresh.ts +7 -0
  109. package/src/protocols/signing.ts +9 -0
  110. package/src/rpc/RPCProvider.ts +7 -0
  111. package/src/rpc/methods.ts +7 -0
  112. package/src/websocket/coordinator.ts +7 -0
  113. package/src/websocket/messages.ts +11 -0
  114. package/src/websocket/session.ts +7 -0
  115. package/src/wire/format.ts +10 -0
  116. package/src/wire/validation.ts +14 -0
  117. package/test-sdk.js +234 -0
@@ -0,0 +1,317 @@
1
+ import {
2
+ KeygenSession,
3
+ SignSession,
4
+ Keyshare
5
+ } from '@silencelaboratories/dkls-wasm-ll-node';
6
+ import type { PartyConfig, WireMessage } from './types';
7
+ import { ThresholdConfig } from './ThresholdConfig';
8
+ import { DKLSService } from './DKLSService';
9
+
10
+ /**
11
+ * Represents a single party in the MPC protocol
12
+ */
13
+ export class DKLSParty {
14
+ private readonly config: PartyConfig;
15
+ private readonly thresholdConfig: ThresholdConfig;
16
+ private keygenSession?: KeygenSession;
17
+ private signSession?: SignSession;
18
+ private keyshare?: Keyshare;
19
+ private messageQueue: WireMessage[] = [];
20
+
21
+ /**
22
+ * Create a new DKLS party
23
+ * @param config Party configuration
24
+ */
25
+ constructor(config: PartyConfig) {
26
+ this.config = config;
27
+ this.thresholdConfig = new ThresholdConfig(
28
+ config.totalParties,
29
+ config.threshold,
30
+ Array.from({ length: config.totalParties }, (_, i) => i)
31
+ );
32
+
33
+ // Validate party ID
34
+ if (!this.thresholdConfig.isValidParty(config.partyId)) {
35
+ throw new Error(`Invalid party ID: ${config.partyId}`);
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Get party ID
41
+ */
42
+ get partyId(): number {
43
+ return this.config.partyId;
44
+ }
45
+
46
+ /**
47
+ * Get party role
48
+ */
49
+ get role(): string {
50
+ return this.config.role ?? 'signer';
51
+ }
52
+
53
+ /**
54
+ * Check if this party is the coordinator
55
+ */
56
+ isCoordinator(): boolean {
57
+ return this.config.role === 'coordinator';
58
+ }
59
+
60
+ /**
61
+ * Initialize key generation session
62
+ */
63
+ initializeKeygen(): void {
64
+ if (this.keygenSession) {
65
+ throw new Error('Keygen session already initialized');
66
+ }
67
+
68
+ this.keygenSession = new KeygenSession(
69
+ this.config.totalParties,
70
+ this.config.threshold,
71
+ this.config.partyId
72
+ );
73
+ }
74
+
75
+ /**
76
+ * Initialize key rotation session
77
+ * @param existingKeyshare Existing keyshare to rotate
78
+ */
79
+ initializeKeyRotation(existingKeyshare: Keyshare): void {
80
+ if (this.keygenSession) {
81
+ throw new Error('Keygen session already initialized');
82
+ }
83
+
84
+ this.keygenSession = KeygenSession.initKeyRotation(existingKeyshare);
85
+ }
86
+
87
+ /**
88
+ * Create first message for current protocol
89
+ * @returns Wire format message
90
+ */
91
+ createFirstMessage(): WireMessage {
92
+ if (this.keygenSession) {
93
+ const msg = this.keygenSession.createFirstMessage();
94
+ return DKLSService.toWireMessage(msg);
95
+ } else if (this.signSession) {
96
+ const msg = this.signSession.createFirstMessage();
97
+ return DKLSService.toWireMessage(msg);
98
+ } else {
99
+ throw new Error('No active session');
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Handle incoming messages
105
+ * @param messages Array of wire format messages
106
+ * @param commitments Optional commitments for keygen round 3
107
+ * @returns Array of response messages
108
+ */
109
+ handleMessages(messages: WireMessage[], commitments?: any[]): WireMessage[] {
110
+ const dklsMessages = messages.map(m => DKLSService.fromWireMessage(m));
111
+
112
+ if (this.keygenSession) {
113
+ const responses = this.keygenSession.handleMessages(dklsMessages, commitments);
114
+ return responses.map(m => DKLSService.toWireMessage(m));
115
+ } else if (this.signSession) {
116
+ const responses = this.signSession.handleMessages(dklsMessages);
117
+ return responses.map(m => DKLSService.toWireMessage(m));
118
+ } else {
119
+ throw new Error('No active session');
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Calculate chain code commitment (for keygen)
125
+ * @returns Commitment data
126
+ */
127
+ calculateChainCodeCommitment(): any {
128
+ if (!this.keygenSession) {
129
+ throw new Error('No active keygen session');
130
+ }
131
+ return this.keygenSession.calculateChainCodeCommitment();
132
+ }
133
+
134
+ /**
135
+ * Finalize key generation and extract keyshare
136
+ * @returns The generated keyshare
137
+ */
138
+ finalizeKeygen(): Keyshare {
139
+ if (!this.keygenSession) {
140
+ throw new Error('No active keygen session');
141
+ }
142
+
143
+ this.keyshare = this.keygenSession.keyshare();
144
+ this.keygenSession = undefined; // Session is consumed
145
+
146
+ return this.keyshare;
147
+ }
148
+
149
+ /**
150
+ * Finalize key rotation
151
+ * @param oldKeyshare The old keyshare being rotated
152
+ */
153
+ finalizeKeyRotation(oldKeyshare: Keyshare): void {
154
+ if (!this.keyshare) {
155
+ throw new Error('No new keyshare generated');
156
+ }
157
+
158
+ this.keyshare.finishKeyRotation(oldKeyshare);
159
+ }
160
+
161
+ /**
162
+ * Initialize signing session
163
+ * @param keyshare Keyshare to use for signing
164
+ * @param derivationPath Derivation path (currently only "m" supported)
165
+ */
166
+ initializeSigning(keyshare?: Keyshare, derivationPath: string = "m"): void {
167
+ if (this.signSession) {
168
+ throw new Error('Sign session already initialized');
169
+ }
170
+
171
+ const shareToUse = keyshare ?? this.keyshare;
172
+ if (!shareToUse) {
173
+ throw new Error('No keyshare available for signing');
174
+ }
175
+
176
+ // SignSession consumes the keyshare
177
+ this.signSession = new SignSession(shareToUse, derivationPath);
178
+
179
+ // Clear stored keyshare if it was consumed
180
+ if (!keyshare && this.keyshare) {
181
+ this.keyshare = undefined;
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Generate last message with actual message hash
187
+ * @param messageHash The message hash to sign
188
+ * @returns Wire format message
189
+ */
190
+ lastMessage(messageHash: Uint8Array): WireMessage {
191
+ if (!this.signSession) {
192
+ throw new Error('No active sign session');
193
+ }
194
+
195
+ const msg = this.signSession.lastMessage(messageHash);
196
+ return DKLSService.toWireMessage(msg);
197
+ }
198
+
199
+ /**
200
+ * Combine messages to produce final signature
201
+ * @param messages Final round messages
202
+ * @returns Signature components [r, s]
203
+ */
204
+ combine(messages: WireMessage[]): [Uint8Array, Uint8Array] {
205
+ if (!this.signSession) {
206
+ throw new Error('No active sign session');
207
+ }
208
+
209
+ const dklsMessages = messages.map(m => DKLSService.fromWireMessage(m));
210
+ const signature = this.signSession.combine(dklsMessages);
211
+
212
+ // Session is consumed after combine
213
+ this.signSession = undefined;
214
+
215
+ // Ensure we have exactly 2 components
216
+ if (!Array.isArray(signature) || signature.length !== 2) {
217
+ throw new Error('Invalid signature format');
218
+ }
219
+
220
+ return [signature[0], signature[1]];
221
+ }
222
+
223
+ /**
224
+ * Get stored keyshare
225
+ */
226
+ getKeyshare(): Keyshare | undefined {
227
+ return this.keyshare;
228
+ }
229
+
230
+ /**
231
+ * Set keyshare (for restoring from storage)
232
+ * @param keyshare Keyshare to set
233
+ */
234
+ setKeyshare(keyshare: Keyshare): void {
235
+ this.keyshare = keyshare;
236
+ }
237
+
238
+ /**
239
+ * Serialize keyshare to base64
240
+ * @returns Base64 encoded keyshare or undefined
241
+ */
242
+ serializeKeyshare(): string | undefined {
243
+ if (!this.keyshare) {
244
+ return undefined;
245
+ }
246
+
247
+ const bytes = this.keyshare.toBytes();
248
+ return Buffer.from(bytes).toString('base64');
249
+ }
250
+
251
+ /**
252
+ * Restore keyshare from base64
253
+ * @param data Base64 encoded keyshare
254
+ */
255
+ deserializeKeyshare(data: string): void {
256
+ const bytes = new Uint8Array(Buffer.from(data, 'base64'));
257
+ this.keyshare = Keyshare.fromBytes(bytes);
258
+ }
259
+
260
+ /**
261
+ * Add message to queue
262
+ * @param message Wire format message
263
+ */
264
+ queueMessage(message: WireMessage): void {
265
+ this.messageQueue.push(message);
266
+ }
267
+
268
+ /**
269
+ * Get and clear message queue
270
+ * @returns Queued messages
271
+ */
272
+ getQueuedMessages(): WireMessage[] {
273
+ const messages = [...this.messageQueue];
274
+ this.messageQueue = [];
275
+ return messages;
276
+ }
277
+
278
+ /**
279
+ * Get messages for this party from a list
280
+ * @param messages Array of messages
281
+ * @returns Messages intended for this party
282
+ */
283
+ filterIncomingMessages(messages: WireMessage[]): WireMessage[] {
284
+ return messages.filter(m =>
285
+ m.to_id === undefined || // Broadcast message
286
+ m.to_id === this.partyId // P2P message for this party
287
+ ).filter(m =>
288
+ m.from_id !== this.partyId // Exclude own messages
289
+ );
290
+ }
291
+
292
+ /**
293
+ * Check if party has an active session
294
+ */
295
+ hasActiveSession(): boolean {
296
+ return !!(this.keygenSession || this.signSession);
297
+ }
298
+
299
+ /**
300
+ * Get current session type
301
+ */
302
+ getSessionType(): 'keygen' | 'signing' | 'none' {
303
+ if (this.keygenSession) return 'keygen';
304
+ if (this.signSession) return 'signing';
305
+ return 'none';
306
+ }
307
+
308
+ /**
309
+ * Clear all sessions and state
310
+ */
311
+ reset(): void {
312
+ this.keygenSession = undefined;
313
+ this.signSession = undefined;
314
+ this.messageQueue = [];
315
+ // Note: We don't clear keyshare as it might be needed later
316
+ }
317
+ }