@vocdoni/davinci-sdk 0.0.1 → 0.0.3
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/README.md +297 -43
- package/dist/contracts.d.ts +65 -54
- package/dist/index.d.ts +1316 -194
- package/dist/index.js +1560 -300
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1554 -294
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +3148 -1888
- package/dist/sequencer.d.ts +2 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Vocdoni DaVinci SDK
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/js/%40vocdoni%2Fdavinci-sdk)
|
|
4
|
-
[](https://www.gnu.org/licenses/agpl-3.0)
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
[](#)
|
|
7
7
|
|
|
@@ -20,44 +20,32 @@ yarn add @vocdoni/davinci-sdk
|
|
|
20
20
|
### Basic Usage
|
|
21
21
|
|
|
22
22
|
```typescript
|
|
23
|
-
import { DavinciSDK,
|
|
23
|
+
import { DavinciSDK, PlainCensus, WeightedCensus } from '@vocdoni/davinci-sdk';
|
|
24
24
|
import { Wallet } from 'ethers';
|
|
25
25
|
|
|
26
26
|
// Initialize the SDK
|
|
27
27
|
const wallet = new Wallet('your-private-key');
|
|
28
28
|
const sdk = new DavinciSDK({
|
|
29
29
|
signer: wallet,
|
|
30
|
-
|
|
30
|
+
sequencerUrl: 'https://sequencer-dev.davinci.vote',
|
|
31
|
+
censusUrl: 'https://c3-dev.davinci.vote'
|
|
31
32
|
});
|
|
32
33
|
|
|
33
34
|
await sdk.init();
|
|
34
35
|
|
|
35
36
|
// 1. Create a census with eligible voters
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
{ key: "0x3456789012345678901234567890123456789012", weight: "2" } // Higher weight
|
|
43
|
-
];
|
|
44
|
-
|
|
45
|
-
await sdk.api.census.addParticipants(censusId, participants);
|
|
46
|
-
|
|
47
|
-
// Publish the census to get the root
|
|
48
|
-
const publishResult = await sdk.api.census.publishCensus(censusId);
|
|
49
|
-
const censusSize = await sdk.api.census.getCensusSize(publishResult.root);
|
|
37
|
+
const census = new PlainCensus(); // or WeightedCensus for custom voting power
|
|
38
|
+
census.add([
|
|
39
|
+
'0x1234567890123456789012345678901234567890',
|
|
40
|
+
'0x2345678901234567890123456789012345678901',
|
|
41
|
+
'0x3456789012345678901234567890123456789012'
|
|
42
|
+
]);
|
|
50
43
|
|
|
51
44
|
// 2. Create a voting process
|
|
52
45
|
const process = await sdk.createProcess({
|
|
53
46
|
title: "Community Decision",
|
|
54
47
|
description: "Vote on our next community initiative",
|
|
55
|
-
census:
|
|
56
|
-
type: CensusOrigin.CensusOriginMerkleTree,
|
|
57
|
-
root: publishResult.root,
|
|
58
|
-
size: censusSize,
|
|
59
|
-
uri: publishResult.uri
|
|
60
|
-
},
|
|
48
|
+
census: census,
|
|
61
49
|
timing: {
|
|
62
50
|
startDate: new Date("2024-12-01T10:00:00Z"),
|
|
63
51
|
duration: 86400 // 24 hours in seconds
|
|
@@ -76,7 +64,8 @@ const process = await sdk.createProcess({
|
|
|
76
64
|
const voterWallet = new Wallet('voter-private-key'); // Must be one of the census participants
|
|
77
65
|
const voterSdk = new DavinciSDK({
|
|
78
66
|
signer: voterWallet,
|
|
79
|
-
|
|
67
|
+
sequencerUrl: 'https://sequencer-dev.davinci.vote'
|
|
68
|
+
// No censusUrl needed for voting-only operations
|
|
80
69
|
});
|
|
81
70
|
await voterSdk.init();
|
|
82
71
|
|
|
@@ -157,6 +146,190 @@ pnpm add @vocdoni/davinci-sdk ethers
|
|
|
157
146
|
- **Process**: Container for all voting parameters and metadata
|
|
158
147
|
- **Proof**: Cryptographic evidence that a vote is valid
|
|
159
148
|
|
|
149
|
+
## 📋 Census Management
|
|
150
|
+
|
|
151
|
+
The SDK provides simple-to-use census classes that make voter management easy. Census objects are **automatically published** when creating a process - no manual steps required!
|
|
152
|
+
|
|
153
|
+
### Census Types
|
|
154
|
+
|
|
155
|
+
#### PlainCensus - Equal Voting Power
|
|
156
|
+
|
|
157
|
+
Everyone gets the same voting weight (weight = 1).
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
import { PlainCensus } from '@vocdoni/davinci-sdk';
|
|
161
|
+
|
|
162
|
+
const census = new PlainCensus();
|
|
163
|
+
census.add([
|
|
164
|
+
'0x1234567890123456789012345678901234567890',
|
|
165
|
+
'0xabcdefabcdefabcdefabcdefabcdefabcdefabcd',
|
|
166
|
+
'0x9876543210987654321098765432109876543210'
|
|
167
|
+
]);
|
|
168
|
+
|
|
169
|
+
// Use directly in process creation - SDK auto-publishes!
|
|
170
|
+
const process = await sdk.createProcess({
|
|
171
|
+
census: census, // ✨ Auto-published!
|
|
172
|
+
// ... rest of config
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
#### WeightedCensus - Custom Voting Power
|
|
177
|
+
|
|
178
|
+
Assign different voting weights to participants. Supports flexible weight types: **string**, **number**, or **bigint**.
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
import { WeightedCensus } from '@vocdoni/davinci-sdk';
|
|
182
|
+
|
|
183
|
+
const census = new WeightedCensus();
|
|
184
|
+
|
|
185
|
+
census.add([
|
|
186
|
+
{ key: '0x123...', weight: "1" }, // string
|
|
187
|
+
{ key: '0x456...', weight: 5 }, // number
|
|
188
|
+
{ key: '0x789...', weight: 100n }, // bigint
|
|
189
|
+
]);
|
|
190
|
+
|
|
191
|
+
// Auto-published when creating process
|
|
192
|
+
const process = await sdk.createProcess({
|
|
193
|
+
census: census,
|
|
194
|
+
// ... rest of config
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
#### CspCensus - Certificate Service Provider
|
|
199
|
+
|
|
200
|
+
For external authentication systems.
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import { CspCensus } from '@vocdoni/davinci-sdk';
|
|
204
|
+
|
|
205
|
+
const census = new CspCensus(
|
|
206
|
+
"0x1234567890abcdef", // Root hash (public key)
|
|
207
|
+
"https://csp-server.com", // CSP URL
|
|
208
|
+
1000 // Expected number of voters
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
const process = await sdk.createProcess({
|
|
212
|
+
census: census,
|
|
213
|
+
// ... rest of config
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
#### PublishedCensus - Use Pre-Published Census
|
|
218
|
+
|
|
219
|
+
For censuses already published to the network.
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { PublishedCensus, CensusType } from '@vocdoni/davinci-sdk';
|
|
223
|
+
|
|
224
|
+
const census = new PublishedCensus(
|
|
225
|
+
CensusType.WEIGHTED,
|
|
226
|
+
"0xroot...",
|
|
227
|
+
"ipfs://uri...",
|
|
228
|
+
100 // size
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
const process = await sdk.createProcess({
|
|
232
|
+
census: census,
|
|
233
|
+
// ... rest of config
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Auto-Publishing Feature
|
|
238
|
+
|
|
239
|
+
The SDK automatically publishes unpublished censuses when creating a process:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
const census = new PlainCensus();
|
|
243
|
+
census.add(['0x123...', '0x456...']);
|
|
244
|
+
|
|
245
|
+
console.log(census.isPublished); // false
|
|
246
|
+
|
|
247
|
+
// SDK automatically publishes during process creation
|
|
248
|
+
const process = await sdk.createProcess({
|
|
249
|
+
census: census,
|
|
250
|
+
// ... config
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
console.log(census.isPublished); // true ✅
|
|
254
|
+
console.log(census.censusRoot); // Published root hash
|
|
255
|
+
console.log(census.censusURI); // Published URI
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Flexible Weight Types
|
|
259
|
+
|
|
260
|
+
WeightedCensus accepts weights as strings, numbers, or bigints for maximum flexibility:
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
const census = new WeightedCensus();
|
|
264
|
+
|
|
265
|
+
// String weights (recommended for very large numbers)
|
|
266
|
+
census.add({ key: '0x123...', weight: "999999999999" });
|
|
267
|
+
|
|
268
|
+
// Number weights (easy to use, good for reasonable values)
|
|
269
|
+
census.add({ key: '0x456...', weight: 100 });
|
|
270
|
+
|
|
271
|
+
// BigInt weights (for JavaScript bigint support)
|
|
272
|
+
census.add({ key: '0x789...', weight: 1000000n });
|
|
273
|
+
|
|
274
|
+
// Mix them all!
|
|
275
|
+
census.add([
|
|
276
|
+
{ key: '0xaaa...', weight: "1" },
|
|
277
|
+
{ key: '0xbbb...', weight: 5 },
|
|
278
|
+
{ key: '0xccc...', weight: 10n }
|
|
279
|
+
]);
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Census Operations
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
const census = new WeightedCensus();
|
|
286
|
+
|
|
287
|
+
// Add single participant
|
|
288
|
+
census.add({ key: '0x123...', weight: 5 });
|
|
289
|
+
|
|
290
|
+
// Add multiple participants
|
|
291
|
+
census.add([
|
|
292
|
+
{ key: '0x456...', weight: 10 },
|
|
293
|
+
{ key: '0x789...', weight: 15 }
|
|
294
|
+
]);
|
|
295
|
+
|
|
296
|
+
// Remove participant
|
|
297
|
+
census.remove('0x123...');
|
|
298
|
+
|
|
299
|
+
// Get participant weight
|
|
300
|
+
const weight = census.getWeight('0x456...'); // Returns: "10"
|
|
301
|
+
|
|
302
|
+
// Get all addresses
|
|
303
|
+
const addresses = census.addresses; // ['0x456...', '0x789...']
|
|
304
|
+
|
|
305
|
+
// Get all participants with weights
|
|
306
|
+
const participants = census.participants;
|
|
307
|
+
// [{ key: '0x456...', weight: '10' }, { key: '0x789...', weight: '15' }]
|
|
308
|
+
|
|
309
|
+
// Check if published
|
|
310
|
+
if (census.isPublished) {
|
|
311
|
+
console.log('Root:', census.censusRoot);
|
|
312
|
+
console.log('URI:', census.censusURI);
|
|
313
|
+
console.log('Size:', census.size);
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Manual Census Configuration (Advanced)
|
|
318
|
+
|
|
319
|
+
For advanced use cases, you can still provide census data manually:
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
const process = await sdk.createProcess({
|
|
323
|
+
census: {
|
|
324
|
+
type: CensusOrigin.CensusOriginMerkleTree,
|
|
325
|
+
root: "0xabc...",
|
|
326
|
+
size: 100,
|
|
327
|
+
uri: "ipfs://..."
|
|
328
|
+
},
|
|
329
|
+
// ... rest of config
|
|
330
|
+
});
|
|
331
|
+
```
|
|
332
|
+
|
|
160
333
|
## 📖 API Reference
|
|
161
334
|
|
|
162
335
|
### SDK Initialization
|
|
@@ -166,36 +339,65 @@ pnpm add @vocdoni/davinci-sdk ethers
|
|
|
166
339
|
```typescript
|
|
167
340
|
interface DavinciSDKConfig {
|
|
168
341
|
signer: Signer; // Ethereum signer (required)
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
chain?: 'sepolia' | 'mainnet'; // Blockchain network
|
|
173
|
-
contractAddresses?: { // Custom contract addresses
|
|
342
|
+
sequencerUrl: string; // Sequencer API URL (required)
|
|
343
|
+
censusUrl?: string; // Census API URL (optional, only needed for census creation)
|
|
344
|
+
addresses?: { // Custom contract addresses (optional)
|
|
174
345
|
processRegistry?: string;
|
|
175
346
|
organizationRegistry?: string;
|
|
176
|
-
|
|
347
|
+
stateTransitionVerifier?: string;
|
|
348
|
+
resultsVerifier?: string;
|
|
349
|
+
sequencerRegistry?: string;
|
|
177
350
|
};
|
|
178
|
-
|
|
351
|
+
censusProviders?: CensusProviders; // Custom census proof providers (optional)
|
|
352
|
+
verifyCircuitFiles?: boolean; // Verify downloaded circuit files (default: true)
|
|
353
|
+
verifyProof?: boolean; // Verify generated proof before submission (default: true)
|
|
179
354
|
}
|
|
180
355
|
```
|
|
181
356
|
|
|
357
|
+
**Key Points:**
|
|
358
|
+
|
|
359
|
+
- **`sequencerUrl`** (required): The Vocdoni sequencer API endpoint
|
|
360
|
+
- Dev: `https://sequencer-dev.davinci.vote`
|
|
361
|
+
- Staging: `https://sequencer1.davinci.vote`
|
|
362
|
+
- Production: (check latest docs)
|
|
363
|
+
|
|
364
|
+
- **`censusUrl`** (optional): Only required if you're creating censuses from scratch. Not needed for voting-only operations.
|
|
365
|
+
|
|
366
|
+
- **Contract Addresses**: If not provided, the SDK automatically fetches them from the sequencer's `/info` endpoint during initialization. This is the recommended approach.
|
|
367
|
+
|
|
182
368
|
#### Basic Initialization
|
|
183
369
|
|
|
184
370
|
```typescript
|
|
185
371
|
import { DavinciSDK } from '@vocdoni/davinci-sdk';
|
|
186
372
|
import { Wallet } from 'ethers';
|
|
187
373
|
|
|
374
|
+
// Development environment
|
|
188
375
|
const sdk = new DavinciSDK({
|
|
189
376
|
signer: new Wallet('your-private-key'),
|
|
190
|
-
|
|
377
|
+
sequencerUrl: 'https://sequencer-dev.davinci.vote',
|
|
378
|
+
censusUrl: 'https://c3-dev.davinci.vote'
|
|
191
379
|
});
|
|
192
380
|
|
|
193
381
|
await sdk.init();
|
|
194
382
|
```
|
|
195
383
|
|
|
384
|
+
**Automatic Contract Address Fetching:**
|
|
385
|
+
|
|
386
|
+
The SDK automatically fetches contract addresses from the sequencer during `init()`:
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
const sdk = new DavinciSDK({
|
|
390
|
+
signer: wallet,
|
|
391
|
+
sequencerUrl: 'https://sequencer-dev.davinci.vote'
|
|
392
|
+
// Contract addresses will be fetched automatically from sequencer
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
await sdk.init(); // Fetches and stores contract addresses
|
|
396
|
+
```
|
|
397
|
+
|
|
196
398
|
### Process Management
|
|
197
399
|
|
|
198
|
-
#### Creating a Process
|
|
400
|
+
#### Creating a Process (Simple)
|
|
199
401
|
|
|
200
402
|
```typescript
|
|
201
403
|
const processResult = await sdk.createProcess({
|
|
@@ -244,6 +446,51 @@ const processResult = await sdk.createProcess({
|
|
|
244
446
|
console.log('Process created:', processResult.processId);
|
|
245
447
|
```
|
|
246
448
|
|
|
449
|
+
#### Creating a Process with Real-Time Status (Stream)
|
|
450
|
+
|
|
451
|
+
For applications that need to show real-time transaction progress to users, use `createProcessStream()`:
|
|
452
|
+
|
|
453
|
+
```typescript
|
|
454
|
+
import { TxStatus } from '@vocdoni/davinci-sdk';
|
|
455
|
+
|
|
456
|
+
const stream = sdk.createProcessStream({
|
|
457
|
+
title: "Election Title",
|
|
458
|
+
// ... same configuration as above
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
// Monitor transaction status in real-time
|
|
462
|
+
for await (const event of stream) {
|
|
463
|
+
switch (event.status) {
|
|
464
|
+
case TxStatus.Pending:
|
|
465
|
+
console.log("📝 Transaction submitted:", event.hash);
|
|
466
|
+
// Update UI to show pending state
|
|
467
|
+
break;
|
|
468
|
+
|
|
469
|
+
case TxStatus.Completed:
|
|
470
|
+
console.log("✅ Process created:", event.response.processId);
|
|
471
|
+
console.log(" Transaction:", event.response.transactionHash);
|
|
472
|
+
// Update UI to show success
|
|
473
|
+
break;
|
|
474
|
+
|
|
475
|
+
case TxStatus.Failed:
|
|
476
|
+
console.error("❌ Transaction failed:", event.error);
|
|
477
|
+
// Update UI to show error
|
|
478
|
+
break;
|
|
479
|
+
|
|
480
|
+
case TxStatus.Reverted:
|
|
481
|
+
console.error("⚠️ Transaction reverted:", event.reason);
|
|
482
|
+
// Update UI to show revert reason
|
|
483
|
+
break;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
**When to use each method:**
|
|
489
|
+
|
|
490
|
+
- Use `createProcess()` for simple scripts and when you don't need transaction progress updates
|
|
491
|
+
- Use `createProcessStream()` for UI applications where users need real-time feedback during transaction processing
|
|
492
|
+
|
|
493
|
+
|
|
247
494
|
#### Retrieving Process Information
|
|
248
495
|
|
|
249
496
|
```typescript
|
|
@@ -315,7 +562,8 @@ async function completeVotingExample() {
|
|
|
315
562
|
const organizerWallet = new Wallet('organizer-private-key');
|
|
316
563
|
const sdk = new DavinciSDK({
|
|
317
564
|
signer: organizerWallet,
|
|
318
|
-
|
|
565
|
+
sequencerUrl: 'https://sequencer-dev.davinci.vote',
|
|
566
|
+
censusUrl: 'https://c3-dev.davinci.vote'
|
|
319
567
|
});
|
|
320
568
|
await sdk.init();
|
|
321
569
|
|
|
@@ -370,7 +618,8 @@ async function completeVotingExample() {
|
|
|
370
618
|
const voterWallet = voters[0]; // Use first voter from census
|
|
371
619
|
const voterSdk = new DavinciSDK({
|
|
372
620
|
signer: voterWallet,
|
|
373
|
-
|
|
621
|
+
sequencerUrl: 'https://sequencer-dev.davinci.vote'
|
|
622
|
+
// No censusUrl needed for voting-only operations
|
|
374
623
|
});
|
|
375
624
|
await voterSdk.init();
|
|
376
625
|
|
|
@@ -414,7 +663,7 @@ async function browserVotingExample() {
|
|
|
414
663
|
// Initialize SDK
|
|
415
664
|
const sdk = new DavinciSDK({
|
|
416
665
|
signer,
|
|
417
|
-
|
|
666
|
+
sequencerUrl: 'https://sequencer.davinci.vote' // Production URL
|
|
418
667
|
});
|
|
419
668
|
await sdk.init();
|
|
420
669
|
|
|
@@ -438,10 +687,9 @@ async function browserVotingExample() {
|
|
|
438
687
|
```typescript
|
|
439
688
|
const sdk = new DavinciSDK({
|
|
440
689
|
signer: wallet,
|
|
441
|
-
chain: 'sepolia',
|
|
442
690
|
sequencerUrl: 'https://your-custom-sequencer.com',
|
|
443
691
|
censusUrl: 'https://your-custom-census.com',
|
|
444
|
-
|
|
692
|
+
addresses: {
|
|
445
693
|
processRegistry: '0x...',
|
|
446
694
|
organizationRegistry: '0x...',
|
|
447
695
|
stateTransitionVerifier: '0x...',
|
|
@@ -450,14 +698,18 @@ const sdk = new DavinciSDK({
|
|
|
450
698
|
});
|
|
451
699
|
```
|
|
452
700
|
|
|
453
|
-
###
|
|
701
|
+
### Automatic Contract Address Fetching (Default Behavior)
|
|
702
|
+
|
|
703
|
+
By default, the SDK automatically fetches contract addresses from the sequencer's `/info` endpoint:
|
|
454
704
|
|
|
455
705
|
```typescript
|
|
456
706
|
const sdk = new DavinciSDK({
|
|
457
707
|
signer: wallet,
|
|
458
|
-
|
|
459
|
-
|
|
708
|
+
sequencerUrl: 'https://sequencer-dev.davinci.vote'
|
|
709
|
+
// Contract addresses fetched automatically during init()
|
|
460
710
|
});
|
|
711
|
+
|
|
712
|
+
await sdk.init(); // Fetches addresses from sequencer
|
|
461
713
|
```
|
|
462
714
|
|
|
463
715
|
### Custom Vote Randomness
|
|
@@ -466,7 +718,7 @@ const sdk = new DavinciSDK({
|
|
|
466
718
|
const vote = await sdk.submitVote({
|
|
467
719
|
processId: "0x...",
|
|
468
720
|
choices: [1],
|
|
469
|
-
randomness: "your-custom-randomness-hex"
|
|
721
|
+
randomness: "your-custom-randomness-hex"
|
|
470
722
|
});
|
|
471
723
|
```
|
|
472
724
|
|
|
@@ -600,7 +852,9 @@ yarn format
|
|
|
600
852
|
|
|
601
853
|
## 📄 License
|
|
602
854
|
|
|
603
|
-
This project is licensed under the
|
|
855
|
+
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0) - see the [LICENSE](LICENSE) file for details.
|
|
856
|
+
|
|
857
|
+
The AGPL-3.0 is a copyleft license that requires anyone who distributes your code or a derivative work to make the source available under the same terms. If your application is a web service, users interacting with it remotely must also be able to access the source code.
|
|
604
858
|
|
|
605
859
|
## 🆘 Support
|
|
606
860
|
|
package/dist/contracts.d.ts
CHANGED
|
@@ -1,53 +1,6 @@
|
|
|
1
|
-
import { ContractTransactionResponse, ContractRunner } from 'ethers';
|
|
1
|
+
import { ContractTransactionResponse, BaseContract, ContractEventName, EventFilter, ContractRunner } from 'ethers';
|
|
2
2
|
import * as _vocdoni_davinci_contracts_dist_src_ProcessRegistry from '@vocdoni/davinci-contracts/dist/src/ProcessRegistry';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Interface defining the structure of deployed contract addresses across different networks.
|
|
6
|
-
* Each contract has addresses for both Sepolia testnet and Ethereum mainnet.
|
|
7
|
-
*/
|
|
8
|
-
interface DeployedAddresses {
|
|
9
|
-
/** Process Registry contract addresses */
|
|
10
|
-
processRegistry: {
|
|
11
|
-
/** Sepolia testnet address */
|
|
12
|
-
sepolia: string;
|
|
13
|
-
/** Ethereum mainnet address */
|
|
14
|
-
mainnet: string;
|
|
15
|
-
};
|
|
16
|
-
/** Organization Registry contract addresses */
|
|
17
|
-
organizationRegistry: {
|
|
18
|
-
/** Sepolia testnet address */
|
|
19
|
-
sepolia: string;
|
|
20
|
-
/** Ethereum mainnet address */
|
|
21
|
-
mainnet: string;
|
|
22
|
-
};
|
|
23
|
-
/** State Transition Verifier contract addresses */
|
|
24
|
-
stateTransitionVerifierGroth16: {
|
|
25
|
-
/** Sepolia testnet address */
|
|
26
|
-
sepolia: string;
|
|
27
|
-
/** Ethereum mainnet address */
|
|
28
|
-
mainnet: string;
|
|
29
|
-
};
|
|
30
|
-
/** Results Verifier contract addresses */
|
|
31
|
-
resultsVerifierGroth16: {
|
|
32
|
-
/** Sepolia testnet address */
|
|
33
|
-
sepolia: string;
|
|
34
|
-
/** Ethereum mainnet address */
|
|
35
|
-
mainnet: string;
|
|
36
|
-
};
|
|
37
|
-
/** Sequencer Registry contract addresses */
|
|
38
|
-
sequencerRegistry: {
|
|
39
|
-
/** Sepolia testnet address */
|
|
40
|
-
sepolia: string;
|
|
41
|
-
/** Ethereum mainnet address */
|
|
42
|
-
mainnet: string;
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Deployed contract addresses imported from @vocdoni/davinci-contracts package.
|
|
47
|
-
* These addresses are used to interact with the Vocdoni voting protocol contracts
|
|
48
|
-
* on different networks.
|
|
49
|
-
*/
|
|
50
|
-
declare const deployedAddresses: DeployedAddresses;
|
|
51
4
|
/**
|
|
52
5
|
* Enum representing the possible states of a transaction during its lifecycle.
|
|
53
6
|
* Used to track and report transaction status in the event stream.
|
|
@@ -83,9 +36,14 @@ type TxStatusEvent<T = any> = {
|
|
|
83
36
|
};
|
|
84
37
|
/**
|
|
85
38
|
* Abstract base class providing common functionality for smart contract interactions.
|
|
86
|
-
* Implements transaction handling, status monitoring,
|
|
39
|
+
* Implements transaction handling, status monitoring, event normalization, and
|
|
40
|
+
* event listener management with automatic fallback for RPCs that don't support eth_newFilter.
|
|
87
41
|
*/
|
|
88
42
|
declare abstract class SmartContractService {
|
|
43
|
+
/** Active polling intervals for event listeners using fallback mode */
|
|
44
|
+
private pollingIntervals;
|
|
45
|
+
/** Default polling interval in milliseconds for event listener fallback */
|
|
46
|
+
protected eventPollingInterval: number;
|
|
89
47
|
/**
|
|
90
48
|
* Sends a transaction and yields status events during its lifecycle.
|
|
91
49
|
* This method handles the complete transaction flow from submission to completion,
|
|
@@ -156,6 +114,59 @@ declare abstract class SmartContractService {
|
|
|
156
114
|
* ```
|
|
157
115
|
*/
|
|
158
116
|
protected normalizeListener<Args extends any[]>(callback: (...args: Args) => void): (...listenerArgs: any[]) => void;
|
|
117
|
+
/**
|
|
118
|
+
* Sets up an event listener with automatic fallback for RPCs that don't support eth_newFilter.
|
|
119
|
+
* First attempts to use contract.on() which relies on eth_newFilter. If the RPC doesn't support
|
|
120
|
+
* this method (error code -32601), automatically falls back to polling with queryFilter.
|
|
121
|
+
*
|
|
122
|
+
* @template Args - Tuple type representing the event arguments
|
|
123
|
+
* @param contract - The contract instance to listen to
|
|
124
|
+
* @param eventFilter - The event filter to listen for
|
|
125
|
+
* @param callback - The callback function to invoke when the event occurs
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* this.setupEventListener(
|
|
130
|
+
* this.contract,
|
|
131
|
+
* this.contract.filters.Transfer(),
|
|
132
|
+
* (from: string, to: string, amount: bigint) => {
|
|
133
|
+
* console.log(`Transfer: ${from} -> ${to}: ${amount}`);
|
|
134
|
+
* }
|
|
135
|
+
* );
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
protected setupEventListener<Args extends any[]>(contract: BaseContract, eventFilter: ContractEventName | EventFilter, callback: (...args: Args) => void): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Checks if an error indicates that the RPC method is unsupported or filter operations are not working.
|
|
141
|
+
* This includes:
|
|
142
|
+
* - Method not found (-32601): RPC doesn't support eth_newFilter
|
|
143
|
+
* - Filter not found (-32000): RPC doesn't properly maintain filters
|
|
144
|
+
*
|
|
145
|
+
* @param error - The error to check
|
|
146
|
+
* @returns true if the error indicates unsupported or broken filter functionality
|
|
147
|
+
*/
|
|
148
|
+
private isUnsupportedMethodError;
|
|
149
|
+
/**
|
|
150
|
+
* Sets up a polling-based event listener as fallback when eth_newFilter is not supported.
|
|
151
|
+
* Periodically queries for new events and invokes the callback for each new event found.
|
|
152
|
+
*
|
|
153
|
+
* @template Args - Tuple type representing the event arguments
|
|
154
|
+
* @param contract - The contract instance to poll
|
|
155
|
+
* @param eventFilter - The event filter to poll for
|
|
156
|
+
* @param callback - The callback function to invoke for each event
|
|
157
|
+
*/
|
|
158
|
+
private setupPollingListener;
|
|
159
|
+
/**
|
|
160
|
+
* Clears all active polling intervals.
|
|
161
|
+
* Should be called when removing all listeners or cleaning up the service.
|
|
162
|
+
*/
|
|
163
|
+
protected clearPollingIntervals(): void;
|
|
164
|
+
/**
|
|
165
|
+
* Sets the polling interval for event listeners using the fallback mechanism.
|
|
166
|
+
*
|
|
167
|
+
* @param intervalMs - Polling interval in milliseconds
|
|
168
|
+
*/
|
|
169
|
+
setEventPollingInterval(intervalMs: number): void;
|
|
159
170
|
}
|
|
160
171
|
|
|
161
172
|
/**
|
|
@@ -359,7 +370,7 @@ interface BallotMode {
|
|
|
359
370
|
maxValueSum: string;
|
|
360
371
|
minValueSum: string;
|
|
361
372
|
}
|
|
362
|
-
interface
|
|
373
|
+
interface CensusData {
|
|
363
374
|
censusOrigin: CensusOrigin;
|
|
364
375
|
maxVotes: string;
|
|
365
376
|
censusRoot: string;
|
|
@@ -470,13 +481,13 @@ declare class ProcessRegistryService extends SmartContractService {
|
|
|
470
481
|
}>;
|
|
471
482
|
getRVerifier(): Promise<string>;
|
|
472
483
|
getSTVerifier(): Promise<string>;
|
|
473
|
-
newProcess(status: ProcessStatus, startTime: number, duration: number, ballotMode: BallotMode, census:
|
|
484
|
+
newProcess(status: ProcessStatus, startTime: number, duration: number, ballotMode: BallotMode, census: CensusData, metadata: string, encryptionKey: EncryptionKey, initStateRoot: bigint): AsyncGenerator<TxStatusEvent<{
|
|
474
485
|
success: boolean;
|
|
475
486
|
}>, void, unknown>;
|
|
476
487
|
setProcessStatus(processID: string, newStatus: ProcessStatus): AsyncGenerator<TxStatusEvent<{
|
|
477
488
|
success: boolean;
|
|
478
489
|
}>, void, unknown>;
|
|
479
|
-
setProcessCensus(processID: string, census:
|
|
490
|
+
setProcessCensus(processID: string, census: CensusData): AsyncGenerator<TxStatusEvent<{
|
|
480
491
|
success: boolean;
|
|
481
492
|
}>, void, unknown>;
|
|
482
493
|
setProcessDuration(processID: string, duration: number): AsyncGenerator<TxStatusEvent<{
|
|
@@ -508,5 +519,5 @@ declare class ProcessRegistryService extends SmartContractService {
|
|
|
508
519
|
removeAllListeners(): void;
|
|
509
520
|
}
|
|
510
521
|
|
|
511
|
-
export { ContractServiceError, OrganizationAdministratorError, OrganizationCreateError, OrganizationDeleteError, OrganizationRegistryService, OrganizationUpdateError, ProcessCensusError, ProcessCreateError, ProcessDurationError, ProcessRegistryService, ProcessResultError, ProcessStateTransitionError, ProcessStatus, ProcessStatusError, SmartContractService, TxStatus
|
|
512
|
-
export type {
|
|
522
|
+
export { ContractServiceError, OrganizationAdministratorError, OrganizationCreateError, OrganizationDeleteError, OrganizationRegistryService, OrganizationUpdateError, ProcessCensusError, ProcessCreateError, ProcessDurationError, ProcessRegistryService, ProcessResultError, ProcessStateTransitionError, ProcessStatus, ProcessStatusError, SmartContractService, TxStatus };
|
|
523
|
+
export type { EntityCallback, OrganizationAdministratorAddedCallback, OrganizationAdministratorRemovedCallback, OrganizationCreatedCallback, OrganizationInfo, OrganizationUpdatedCallback, ProcessCensusUpdatedCallback, ProcessCreatedCallback, ProcessDurationChangedCallback, ProcessResultsSetCallback, ProcessStateRootUpdatedCallback, ProcessStatusChangedCallback, TxStatusEvent };
|