@claritydao/midnight-agora-sdk 0.2.0 → 1.2.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.
Files changed (47) hide show
  1. package/README.md +58 -55
  2. package/dist/browser-providers.d.ts +24 -19
  3. package/dist/browser-providers.d.ts.map +1 -1
  4. package/dist/browser-providers.js +654 -139
  5. package/dist/browser-providers.js.map +1 -1
  6. package/dist/common-types.d.ts +13 -24
  7. package/dist/common-types.d.ts.map +1 -1
  8. package/dist/common-types.js +1 -1
  9. package/dist/common-types.js.map +1 -1
  10. package/dist/governor-api.d.ts +42 -17
  11. package/dist/governor-api.d.ts.map +1 -1
  12. package/dist/governor-api.js +233 -248
  13. package/dist/governor-api.js.map +1 -1
  14. package/dist/index.d.ts +11 -10
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +10 -9
  17. package/dist/index.js.map +1 -1
  18. package/dist/manager.d.ts +11 -11
  19. package/dist/manager.d.ts.map +1 -1
  20. package/dist/manager.js +17 -20
  21. package/dist/manager.js.map +1 -1
  22. package/dist/types.d.ts +9 -17
  23. package/dist/types.d.ts.map +1 -1
  24. package/dist/types.js.map +1 -1
  25. package/package.json +26 -26
  26. package/.prettierrc +0 -1
  27. package/LICENSE +0 -0
  28. package/eslint.config.mjs +0 -48
  29. package/src/browser-providers.ts +0 -278
  30. package/src/common-types.ts +0 -51
  31. package/src/errors.ts +0 -124
  32. package/src/governor-api.ts +0 -948
  33. package/src/index.ts +0 -51
  34. package/src/manager.ts +0 -205
  35. package/src/types.ts +0 -403
  36. package/src/utils/index.ts +0 -60
  37. package/src/validators.ts +0 -245
  38. package/test/README.md +0 -409
  39. package/test/errors.test.ts +0 -179
  40. package/test/integration/governor-api.test.ts +0 -370
  41. package/test/mocks/providers.ts +0 -130
  42. package/test/types.test.ts +0 -112
  43. package/test/utils.test.ts +0 -111
  44. package/test/validators.test.ts +0 -368
  45. package/test/wasm-init.test.ts +0 -132
  46. package/tsconfig.json +0 -18
  47. package/vitest.config.ts +0 -9
package/src/index.ts DELETED
@@ -1,51 +0,0 @@
1
- export { GovernorAPI, type DeployedGovernorAPI } from "./governor-api";
2
- export { initializeProviders } from "./browser-providers";
3
- export {
4
- GovernorManager,
5
- type DeployedGovernorAPIProvider,
6
- type GovernorDeployment,
7
- type InProgressGovernorDeployment,
8
- type DeployedGovernorDeployment,
9
- type FailedGovernorDeployment
10
- } from "./manager";
11
- export * from "./common-types";
12
- export * as utils from "./utils/index";
13
-
14
- // Export comprehensive type definitions
15
- export type {
16
- DeploymentConfig,
17
- GovernanceConfig,
18
- GovernorConfig,
19
- TokenConfig,
20
- ProposalAction,
21
- StakeInfo,
22
- ProposalDetails,
23
- EffectDetails,
24
- VoteCount,
25
- GovernorStatus,
26
- GovernorValue,
27
- StakeRecord
28
- } from "./types";
29
-
30
- // Export enums
31
- export { VoteChoice, ProposalStatus } from "./types";
32
-
33
- // Export configuration presets
34
- export { ConfigPresets } from "./types";
35
-
36
- // Export all error classes
37
- export {
38
- GovernorSDKError,
39
- WalletNotConnectedError,
40
- InsufficientStakeError,
41
- InvalidParameterError,
42
- ContractNotFoundError,
43
- ProposalNotFoundError,
44
- TransactionError,
45
- DeploymentError,
46
- InvalidConfigurationError,
47
- NetworkNotConfiguredError
48
- } from "./errors";
49
-
50
- // Export validators for advanced usage
51
- export * as validators from "./validators";
package/src/manager.ts DELETED
@@ -1,205 +0,0 @@
1
- import {
2
- type DeployedGovernorAPI,
3
- GovernorAPI,
4
- type GovernorProviders
5
- } from "./governor-api";
6
- import { initializeProviders } from "./browser-providers";
7
- import { type ContractAddress } from "@midnight-ntwrk/compact-runtime";
8
- import { BehaviorSubject, type Observable } from "rxjs";
9
- import { type Logger } from "pino";
10
- import type { DeploymentConfig } from "./types";
11
-
12
- /**
13
- * An in-progress governor deployment.
14
- */
15
- export interface InProgressGovernorDeployment {
16
- readonly status: "in-progress";
17
- }
18
-
19
- /**
20
- * A deployed governor deployment.
21
- */
22
- export interface DeployedGovernorDeployment {
23
- readonly status: "deployed";
24
-
25
- /**
26
- * The {@link DeployedGovernorAPI} instance when connected to an on network governor contract.
27
- */
28
- readonly api: DeployedGovernorAPI;
29
- }
30
-
31
- /**
32
- * A failed governor deployment.
33
- */
34
- export interface FailedGovernorDeployment {
35
- readonly status: "failed";
36
-
37
- /**
38
- * The error that caused the deployment to fail.
39
- */
40
- readonly error: Error;
41
- }
42
-
43
- /**
44
- * A governor deployment.
45
- */
46
- export type GovernorDeployment =
47
- | InProgressGovernorDeployment
48
- | DeployedGovernorDeployment
49
- | FailedGovernorDeployment;
50
-
51
- /**
52
- * Provides access to governor deployments.
53
- */
54
- export interface DeployedGovernorAPIProvider {
55
- /**
56
- * Gets the observable set of governor deployments.
57
- *
58
- * @remarks
59
- * This property represents an observable array of {@link GovernorDeployment}, each also an
60
- * observable. Changes to the array will be emitted as governors are resolved (deployed or joined),
61
- * while changes to each underlying governor can be observed via each item in the array.
62
- */
63
- readonly governorDeployments$: Observable<
64
- Array<Observable<GovernorDeployment>>
65
- >;
66
-
67
- /**
68
- * Joins or deploys a governor contract.
69
- *
70
- * @param contractAddress An optional contract address to use when resolving.
71
- * @returns An observable governor deployment.
72
- *
73
- * @remarks
74
- * For a given `contractAddress`, the method will attempt to find and join the identified governor
75
- * contract; otherwise it will attempt to deploy a new one.
76
- */
77
- readonly resolve: (
78
- contractAddress?: ContractAddress
79
- ) => Observable<GovernorDeployment>;
80
- }
81
-
82
- /**
83
- * A {@link DeployedGovernorAPIProvider} that manages governor deployments in a browser setting.
84
- *
85
- * @remarks
86
- * {@link GovernorManager} configures and manages a connection to the Midnight Lace
87
- * wallet, along with a collection of additional providers that work in a web-browser setting.
88
- */
89
- export class GovernorManager implements DeployedGovernorAPIProvider {
90
- readonly #governorDeploymentsSubject: BehaviorSubject<
91
- Array<BehaviorSubject<GovernorDeployment>>
92
- >;
93
- #initializedProviders: Promise<GovernorProviders> | undefined;
94
-
95
- /**
96
- * Initializes a new {@link GovernorManager} instance.
97
- *
98
- * @param deploymentConfig The deployment configuration for the governor contract.
99
- * @param logger The `pino` logger to for logging.
100
- * @param networkId The network ID to connect to (e.g., 'testnet', 'undeployed'). Defaults to 'testnet'.
101
- */
102
- constructor(
103
- private readonly deploymentConfig: DeploymentConfig,
104
- private readonly logger: Logger,
105
- private readonly networkId: string = "testnet"
106
- ) {
107
- this.#governorDeploymentsSubject = new BehaviorSubject<
108
- Array<BehaviorSubject<GovernorDeployment>>
109
- >([]);
110
- this.governorDeployments$ = this.#governorDeploymentsSubject;
111
- }
112
-
113
- /** @inheritdoc */
114
- readonly governorDeployments$: Observable<
115
- Array<Observable<GovernorDeployment>>
116
- >;
117
-
118
- /** @inheritdoc */
119
- resolve(contractAddress?: ContractAddress): Observable<GovernorDeployment> {
120
- const deployments = this.#governorDeploymentsSubject.value;
121
- let deployment = deployments.find(
122
- (deployment) =>
123
- deployment.value.status === "deployed" &&
124
- deployment.value.api.deployedContractAddress === contractAddress
125
- );
126
-
127
- if (deployment) {
128
- return deployment;
129
- }
130
-
131
- deployment = new BehaviorSubject<GovernorDeployment>({
132
- status: "in-progress"
133
- });
134
-
135
- if (contractAddress) {
136
- void this.joinDeployment(deployment, contractAddress);
137
- } else {
138
- void this.deployDeployment(deployment);
139
- }
140
-
141
- this.#governorDeploymentsSubject.next([...deployments, deployment]);
142
-
143
- return deployment;
144
- }
145
-
146
- private getProviders(): Promise<GovernorProviders> {
147
- // We use a cached `Promise` to hold the providers. This will:
148
- //
149
- // 1. Cache and re-use the providers (including the configured connector API), and
150
- // 2. Act as a synchronization point if multiple contract deploys or joins run concurrently.
151
- // Concurrent calls to `getProviders()` will receive, and ultimately await, the same
152
- // `Promise`.
153
- return (
154
- this.#initializedProviders ??
155
- (this.#initializedProviders = initializeProviders(this.logger, this.networkId))
156
- );
157
- }
158
-
159
- private async deployDeployment(
160
- deployment: BehaviorSubject<GovernorDeployment>
161
- ): Promise<void> {
162
- try {
163
- const providers = await this.getProviders();
164
- const api = await GovernorAPI.deploy(
165
- providers,
166
- this.deploymentConfig,
167
- this.logger
168
- );
169
-
170
- deployment.next({
171
- status: "deployed",
172
- api
173
- });
174
- } catch (error: unknown) {
175
- deployment.next({
176
- status: "failed",
177
- error: error instanceof Error ? error : new Error(String(error))
178
- });
179
- }
180
- }
181
-
182
- private async joinDeployment(
183
- deployment: BehaviorSubject<GovernorDeployment>,
184
- contractAddress: ContractAddress
185
- ): Promise<void> {
186
- try {
187
- const providers = await this.getProviders();
188
- const api = await GovernorAPI.join(
189
- providers,
190
- contractAddress,
191
- this.logger
192
- );
193
-
194
- deployment.next({
195
- status: "deployed",
196
- api
197
- });
198
- } catch (error: unknown) {
199
- deployment.next({
200
- status: "failed",
201
- error: error instanceof Error ? error : new Error(String(error))
202
- });
203
- }
204
- }
205
- }
package/src/types.ts DELETED
@@ -1,403 +0,0 @@
1
- /**
2
- * Type definitions for the Agora DAO Governor SDK.
3
- *
4
- * @module types
5
- */
6
-
7
- /**
8
- * Governance configuration parameters.
9
- */
10
- export interface GovernanceConfig {
11
- /**
12
- * Duration of the voting period in seconds.
13
- * @example BigInt(604800) // 7 days for production
14
- * @example BigInt(300) // 5 minutes for testing
15
- */
16
- votingPeriod: bigint;
17
-
18
- /**
19
- * Minimum number of votes required for a proposal to pass (quorum).
20
- * @example BigInt(100000) // 100K tokens for production
21
- * @example BigInt(100) // 100 tokens for testing
22
- */
23
- quorumThreshold: bigint;
24
-
25
- /**
26
- * Minimum stake required to create a proposal.
27
- * @example BigInt(50000) // 50K tokens for production
28
- * @example BigInt(100) // 100 tokens for testing
29
- */
30
- proposalThreshold: bigint;
31
-
32
- /**
33
- * Maximum lifetime of a proposal in seconds.
34
- * @example BigInt(2592000) // 30 days for production
35
- * @example BigInt(86400) // 1 day for testing
36
- */
37
- proposalLifetime: bigint;
38
-
39
- /**
40
- * Delay before a passed proposal can be executed, in seconds.
41
- * @example BigInt(172800) // 2 days for production
42
- * @example BigInt(60) // 1 minute for testing
43
- */
44
- executionDelay: bigint;
45
-
46
- /**
47
- * Grace period after execution delay before proposal expires, in seconds.
48
- * @example BigInt(604800) // 7 days for production
49
- * @example BigInt(300) // 5 minutes for testing
50
- */
51
- gracePeriod: bigint;
52
-
53
- /**
54
- * Minimum amount that can be staked.
55
- * @example BigInt(1000) // 1K tokens for production
56
- * @example BigInt(10) // 10 tokens for testing
57
- */
58
- minStakeAmount: bigint;
59
-
60
- /**
61
- * Minimum staking period in seconds before tokens can be unstaked.
62
- * @example BigInt(604800) // 7 days for production
63
- * @example BigInt(60) // 1 minute for testing
64
- */
65
- stakingPeriod: bigint;
66
- }
67
-
68
- /**
69
- * Complete governor contract configuration.
70
- */
71
- export interface GovernorConfig {
72
- /** Governance-specific parameters */
73
- governance: GovernanceConfig;
74
-
75
- /** Delay before execution (should match governance.executionDelay) */
76
- executionDelay: bigint;
77
-
78
- /** Grace period for execution (should match governance.gracePeriod) */
79
- gracePeriod: bigint;
80
-
81
- /** Maximum number of active proposals allowed */
82
- maxActiveProposals: bigint;
83
-
84
- /** Proposal lifetime (should match governance.proposalLifetime) */
85
- proposalLifetime: bigint;
86
-
87
- /** Whether emergency veto is enabled */
88
- emergencyVetoEnabled: boolean;
89
-
90
- /**
91
- * Stake threshold required for emergency veto.
92
- * @example BigInt(75000) // 75K tokens for production
93
- * @example BigInt(500) // 500 tokens for testing
94
- */
95
- emergencyVetoThreshold: bigint;
96
- }
97
-
98
- /**
99
- * Token configuration for governor deployment.
100
- */
101
- export interface TokenConfig {
102
- /**
103
- * Token name.
104
- * @example "Agora DAO Token"
105
- */
106
- name: string;
107
-
108
- /**
109
- * Token symbol.
110
- * @example "AGORA"
111
- */
112
- symbol: string;
113
-
114
- /**
115
- * Number of decimal places for token.
116
- * @example BigInt(18) // Standard ERC20
117
- * @example BigInt(6) // USDC-like
118
- */
119
- decimals: bigint;
120
- }
121
-
122
- /**
123
- * Complete deployment configuration for governor contract.
124
- */
125
- export interface DeploymentConfig {
126
- /** Governor configuration */
127
- governor: GovernorConfig;
128
-
129
- /** Token configuration */
130
- token: TokenConfig;
131
-
132
- /**
133
- * Admin key for the contract (32 bytes).
134
- *
135
- * @remarks
136
- * SECURITY: This should be generated securely and stored safely.
137
- * Never use predictable or hardcoded admin keys in production.
138
- *
139
- * @example
140
- * ```typescript
141
- * import { randomBytes } from '@midnight-ntwrk/midnight-js-utils';
142
- * const adminKey = randomBytes(32);
143
- * ```
144
- */
145
- adminKey: Uint8Array;
146
- }
147
-
148
- /**
149
- * Vote choice enumeration.
150
- */
151
- export enum VoteChoice {
152
- /** Vote in favor of the proposal */
153
- For = 0,
154
-
155
- /** Vote against the proposal */
156
- Against = 1,
157
-
158
- /** Abstain from voting */
159
- Abstain = 2
160
- }
161
-
162
- /**
163
- * Proposal action type.
164
- */
165
- export interface ProposalAction {
166
- /** Action type identifier */
167
- typ: number;
168
-
169
- /** Token address for transfer actions */
170
- token: Uint8Array;
171
-
172
- /** Amount for transfer actions */
173
- amount: bigint;
174
-
175
- /** Recipient address for transfer actions */
176
- to: Uint8Array;
177
-
178
- /** Configuration key for config update actions */
179
- configKey: Uint8Array;
180
-
181
- /** Configuration value for config update actions */
182
- configValue: Uint8Array;
183
- }
184
-
185
- /**
186
- * Stake information for a user.
187
- */
188
- export interface StakeInfo {
189
- /** Amount of tokens staked */
190
- stakedAmount: bigint;
191
-
192
- /** Address to which stake is delegated */
193
- delegatedTo: Uint8Array;
194
-
195
- /** Timestamp when stake was registered */
196
- stakedAt: bigint;
197
- }
198
-
199
- /**
200
- * Proposal status enumeration.
201
- */
202
- export enum ProposalStatus {
203
- /** Proposal is pending and not yet active */
204
- Pending = 0,
205
-
206
- /** Proposal is active and accepting votes */
207
- Active = 1,
208
-
209
- /** Proposal voting period has ended, needs finalization */
210
- Succeeded = 2,
211
-
212
- /** Proposal was defeated */
213
- Defeated = 3,
214
-
215
- /** Proposal is queued for execution */
216
- Queued = 4,
217
-
218
- /** Proposal has been executed */
219
- Executed = 5,
220
-
221
- /** Proposal has expired */
222
- Expired = 6,
223
-
224
- /** Proposal was canceled */
225
- Canceled = 7
226
- }
227
-
228
- /**
229
- * Detailed proposal information.
230
- */
231
- export interface ProposalDetails {
232
- /** Unique proposal identifier */
233
- id: bigint;
234
-
235
- /** Current proposal status */
236
- status: ProposalStatus;
237
-
238
- /** Timestamp when voting started */
239
- votingStartTime: bigint;
240
-
241
- /** Timestamp when voting ends */
242
- votingEndTime: bigint;
243
-
244
- /** Address of proposal creator */
245
- creator: Uint8Array;
246
-
247
- /** Number of votes in favor */
248
- votesFor: bigint;
249
-
250
- /** Number of votes against */
251
- votesAgainst: bigint;
252
-
253
- /** Number of abstain votes */
254
- votesAbstain: bigint;
255
-
256
- /** Associated effect ID */
257
- effectId: bigint;
258
-
259
- /** Proposal title */
260
- title: string;
261
-
262
- /** Proposal description */
263
- description: string;
264
- }
265
-
266
- /**
267
- * Effect details for a proposal.
268
- */
269
- export interface EffectDetails {
270
- /** Effect identifier */
271
- id: bigint;
272
-
273
- /** Associated proposal ID */
274
- proposalId: bigint;
275
-
276
- /** Effect status */
277
- status: number;
278
-
279
- /** Actions to be executed */
280
- actions: ProposalAction[];
281
-
282
- /** Timestamp when effect was created */
283
- createdAt: bigint;
284
-
285
- /** Timestamp when effect can be executed */
286
- executableAt: bigint;
287
- }
288
-
289
- /**
290
- * Vote count information for a proposal.
291
- */
292
- export interface VoteCount {
293
- /** Number of votes in favor */
294
- votesFor: bigint;
295
-
296
- /** Number of votes against */
297
- votesAgainst: bigint;
298
-
299
- /** Number of abstain votes */
300
- votesAbstain: bigint;
301
-
302
- /** Total number of votes cast */
303
- totalVotes: bigint;
304
- }
305
-
306
- /**
307
- * Governor contract status.
308
- */
309
- export interface GovernorStatus {
310
- /** Whether the governor is active */
311
- isActive: boolean;
312
-
313
- /** Number of active proposals */
314
- activeProposalCount: bigint;
315
-
316
- /** Number of queued proposals */
317
- queuedProposalCount: bigint;
318
-
319
- /** Current contract time */
320
- currentTime: bigint;
321
-
322
- /** Treasury balance */
323
- treasuryBalance: bigint;
324
- }
325
-
326
- /**
327
- * Governor value display information.
328
- */
329
- export interface GovernorValue {
330
- /** Contract address */
331
- contractAddress: string;
332
-
333
- /** Number of active proposals */
334
- activeProposals: bigint;
335
-
336
- /** Number of queued proposals */
337
- queuedProposals: bigint;
338
-
339
- /** Treasury balance */
340
- treasuryBalance: bigint;
341
-
342
- /** Whether governor is active */
343
- isActive: boolean;
344
- }
345
-
346
- /**
347
- * Stake record information.
348
- */
349
- export interface StakeRecord {
350
- /** User address */
351
- userId: Uint8Array;
352
-
353
- /** Staked amount */
354
- amount: bigint;
355
-
356
- /** Delegated to address */
357
- delegatedTo: Uint8Array;
358
-
359
- /** Stake timestamp */
360
- stakedAt: bigint;
361
-
362
- /** Whether stake is locked */
363
- isLocked: boolean;
364
- }
365
-
366
- /**
367
- * Helper functions for creating production and testing configurations.
368
- */
369
- export const ConfigPresets = {
370
- /**
371
- * Creates a production-ready governance configuration.
372
- *
373
- * @remarks
374
- * Suitable for mainnet deployment with secure parameters.
375
- */
376
- production: (): GovernanceConfig => ({
377
- votingPeriod: BigInt(604800), // 7 days
378
- quorumThreshold: BigInt(100000), // 100K tokens
379
- proposalThreshold: BigInt(50000), // 50K tokens
380
- proposalLifetime: BigInt(2592000), // 30 days
381
- executionDelay: BigInt(172800), // 2 days
382
- gracePeriod: BigInt(604800), // 7 days
383
- minStakeAmount: BigInt(1000), // 1K tokens
384
- stakingPeriod: BigInt(604800) // 7 days
385
- }),
386
-
387
- /**
388
- * Creates a testing governance configuration.
389
- *
390
- * @remarks
391
- * Suitable for testnet/development with shorter periods.
392
- */
393
- testing: (): GovernanceConfig => ({
394
- votingPeriod: BigInt(300), // 5 minutes
395
- quorumThreshold: BigInt(100), // 100 tokens
396
- proposalThreshold: BigInt(100), // 100 tokens
397
- proposalLifetime: BigInt(86400), // 1 day
398
- executionDelay: BigInt(60), // 1 minute
399
- gracePeriod: BigInt(300), // 5 minutes
400
- minStakeAmount: BigInt(10), // 10 tokens
401
- stakingPeriod: BigInt(60) // 1 minute
402
- })
403
- };
@@ -1,60 +0,0 @@
1
- /**
2
- * Provides utility functions.
3
- *
4
- * @module
5
- */
6
-
7
- /**
8
- * Generates a buffer containing a series of randomly generated bytes.
9
- *
10
- * @param length The number of bytes to generate.
11
- * @returns A `Uint8Array` representing `length` randomly generated bytes.
12
- */
13
- export const randomBytes = (length: number): Uint8Array => {
14
- const bytes = new Uint8Array(length);
15
- crypto.getRandomValues(bytes);
16
- return bytes;
17
- };
18
-
19
- /**
20
- * Converts a wallet address string to a Uint8Array (32 bytes).
21
- *
22
- * @param address The wallet address string.
23
- * @returns A 32-byte Uint8Array representation of the address.
24
- */
25
- export const addressToBytes = (address: string): Uint8Array => {
26
- const addressBytes = new Uint8Array(32);
27
- const addressStr = address.replace(/[^0-9a-f]/gi, "");
28
- const addressHex = addressStr.slice(-64);
29
- for (let i = 0; i < Math.min(32, addressHex.length / 2); i++) {
30
- addressBytes[i] = parseInt(addressHex.substr(i * 2, 2), 16);
31
- }
32
- return addressBytes;
33
- };
34
-
35
- /**
36
- * Converts a Uint8Array to a hex string.
37
- *
38
- * @param bytes The bytes to convert.
39
- * @returns Hex string representation.
40
- */
41
- export const bytesToHex = (bytes: Uint8Array): string => {
42
- return Array.from(bytes)
43
- .map((b) => b.toString(16).padStart(2, "0"))
44
- .join("");
45
- };
46
-
47
- /**
48
- * Converts a hex string to a Uint8Array.
49
- *
50
- * @param hex The hex string to convert.
51
- * @returns Uint8Array representation.
52
- */
53
- export const hexToBytes = (hex: string): Uint8Array => {
54
- const cleanHex = hex.replace(/^0x/, "");
55
- const bytes = new Uint8Array(cleanHex.length / 2);
56
- for (let i = 0; i < bytes.length; i++) {
57
- bytes[i] = parseInt(cleanHex.substr(i * 2, 2), 16);
58
- }
59
- return bytes;
60
- };