@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.
- package/README.md +58 -55
- package/dist/browser-providers.d.ts +24 -19
- package/dist/browser-providers.d.ts.map +1 -1
- package/dist/browser-providers.js +654 -139
- package/dist/browser-providers.js.map +1 -1
- package/dist/common-types.d.ts +13 -24
- package/dist/common-types.d.ts.map +1 -1
- package/dist/common-types.js +1 -1
- package/dist/common-types.js.map +1 -1
- package/dist/governor-api.d.ts +42 -17
- package/dist/governor-api.d.ts.map +1 -1
- package/dist/governor-api.js +233 -248
- package/dist/governor-api.js.map +1 -1
- package/dist/index.d.ts +11 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/dist/manager.d.ts +11 -11
- package/dist/manager.d.ts.map +1 -1
- package/dist/manager.js +17 -20
- package/dist/manager.js.map +1 -1
- package/dist/types.d.ts +9 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +26 -26
- package/.prettierrc +0 -1
- package/LICENSE +0 -0
- package/eslint.config.mjs +0 -48
- package/src/browser-providers.ts +0 -278
- package/src/common-types.ts +0 -51
- package/src/errors.ts +0 -124
- package/src/governor-api.ts +0 -948
- package/src/index.ts +0 -51
- package/src/manager.ts +0 -205
- package/src/types.ts +0 -403
- package/src/utils/index.ts +0 -60
- package/src/validators.ts +0 -245
- package/test/README.md +0 -409
- package/test/errors.test.ts +0 -179
- package/test/integration/governor-api.test.ts +0 -370
- package/test/mocks/providers.ts +0 -130
- package/test/types.test.ts +0 -112
- package/test/utils.test.ts +0 -111
- package/test/validators.test.ts +0 -368
- package/test/wasm-init.test.ts +0 -132
- package/tsconfig.json +0 -18
- package/vitest.config.ts +0 -9
package/test/errors.test.ts
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for error classes
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, it, expect } from 'vitest';
|
|
6
|
-
import {
|
|
7
|
-
GovernorSDKError,
|
|
8
|
-
WalletNotConnectedError,
|
|
9
|
-
InsufficientStakeError,
|
|
10
|
-
InvalidParameterError,
|
|
11
|
-
ContractNotFoundError,
|
|
12
|
-
ProposalNotFoundError,
|
|
13
|
-
TransactionError,
|
|
14
|
-
DeploymentError,
|
|
15
|
-
InvalidConfigurationError,
|
|
16
|
-
NetworkNotConfiguredError,
|
|
17
|
-
} from '../src/index';
|
|
18
|
-
|
|
19
|
-
describe('Error Classes', () => {
|
|
20
|
-
describe('GovernorSDKError', () => {
|
|
21
|
-
it('should be an instance of Error', () => {
|
|
22
|
-
const error = new GovernorSDKError('test error');
|
|
23
|
-
expect(error).toBeInstanceOf(Error);
|
|
24
|
-
expect(error.message).toBe('test error');
|
|
25
|
-
expect(error.name).toBe('GovernorSDKError');
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
describe('WalletNotConnectedError', () => {
|
|
30
|
-
it('should have correct default message', () => {
|
|
31
|
-
const error = new WalletNotConnectedError();
|
|
32
|
-
expect(error).toBeInstanceOf(GovernorSDKError);
|
|
33
|
-
expect(error.message).toBe('Wallet not connected. Please ensure Lace wallet is installed and connected.');
|
|
34
|
-
expect(error.name).toBe('WalletNotConnectedError');
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
describe('InsufficientStakeError', () => {
|
|
39
|
-
it('should include required and actual stake amounts', () => {
|
|
40
|
-
const required = BigInt(1000);
|
|
41
|
-
const actual = BigInt(500);
|
|
42
|
-
const error = new InsufficientStakeError(required, actual);
|
|
43
|
-
|
|
44
|
-
expect(error).toBeInstanceOf(GovernorSDKError);
|
|
45
|
-
expect(error.message).toContain('1000');
|
|
46
|
-
expect(error.message).toContain('500');
|
|
47
|
-
expect(error.name).toBe('InsufficientStakeError');
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('should format bigint values correctly', () => {
|
|
51
|
-
const error = new InsufficientStakeError(BigInt(5000), BigInt(2500));
|
|
52
|
-
expect(error.message).toMatch(/Required.*5000/);
|
|
53
|
-
expect(error.message).toMatch(/Actual.*2500/);
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
describe('InvalidParameterError', () => {
|
|
58
|
-
it('should include parameter name and reason', () => {
|
|
59
|
-
const error = new InvalidParameterError('proposalId', 'must be positive');
|
|
60
|
-
|
|
61
|
-
expect(error).toBeInstanceOf(GovernorSDKError);
|
|
62
|
-
expect(error.message).toContain('proposalId');
|
|
63
|
-
expect(error.message).toContain('must be positive');
|
|
64
|
-
expect(error.name).toBe('InvalidParameterError');
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
describe('ContractNotFoundError', () => {
|
|
69
|
-
it('should include contract address', () => {
|
|
70
|
-
const address = 'test-contract-address';
|
|
71
|
-
const error = new ContractNotFoundError(address);
|
|
72
|
-
|
|
73
|
-
expect(error).toBeInstanceOf(GovernorSDKError);
|
|
74
|
-
expect(error.message).toContain(address);
|
|
75
|
-
expect(error.name).toBe('ContractNotFoundError');
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
describe('ProposalNotFoundError', () => {
|
|
80
|
-
it('should include proposal ID', () => {
|
|
81
|
-
const proposalId = BigInt(42);
|
|
82
|
-
const error = new ProposalNotFoundError(proposalId);
|
|
83
|
-
|
|
84
|
-
expect(error).toBeInstanceOf(GovernorSDKError);
|
|
85
|
-
expect(error.message).toContain('42');
|
|
86
|
-
expect(error.name).toBe('ProposalNotFoundError');
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
describe('TransactionError', () => {
|
|
91
|
-
it('should have custom message', () => {
|
|
92
|
-
const error = new TransactionError('Transaction failed');
|
|
93
|
-
|
|
94
|
-
expect(error).toBeInstanceOf(GovernorSDKError);
|
|
95
|
-
expect(error.message).toBe('Transaction failed: Transaction failed');
|
|
96
|
-
expect(error.name).toBe('TransactionError');
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe('DeploymentError', () => {
|
|
101
|
-
it('should have custom message', () => {
|
|
102
|
-
const error = new DeploymentError('Deployment failed');
|
|
103
|
-
|
|
104
|
-
expect(error).toBeInstanceOf(GovernorSDKError);
|
|
105
|
-
expect(error.message).toBe('Contract deployment failed: Deployment failed');
|
|
106
|
-
expect(error.name).toBe('DeploymentError');
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
describe('InvalidConfigurationError', () => {
|
|
111
|
-
it('should have custom message', () => {
|
|
112
|
-
const error = new InvalidConfigurationError('Invalid voting period');
|
|
113
|
-
|
|
114
|
-
expect(error).toBeInstanceOf(GovernorSDKError);
|
|
115
|
-
expect(error.message).toBe('Invalid configuration: Invalid voting period');
|
|
116
|
-
expect(error.name).toBe('InvalidConfigurationError');
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
describe('NetworkNotConfiguredError', () => {
|
|
121
|
-
it('should have default message', () => {
|
|
122
|
-
const error = new NetworkNotConfiguredError();
|
|
123
|
-
|
|
124
|
-
expect(error).toBeInstanceOf(GovernorSDKError);
|
|
125
|
-
expect(error.message).toBe('Network ID not configured. Set window.midnight.mnLace.networkId before initializing providers.');
|
|
126
|
-
expect(error.name).toBe('NetworkNotConfiguredError');
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
describe('Error Inheritance', () => {
|
|
131
|
-
it('all custom errors should be instances of GovernorSDKError', () => {
|
|
132
|
-
const errors = [
|
|
133
|
-
new WalletNotConnectedError(),
|
|
134
|
-
new InsufficientStakeError(BigInt(100), BigInt(50)),
|
|
135
|
-
new InvalidParameterError('test', 'reason'),
|
|
136
|
-
new ContractNotFoundError('address'),
|
|
137
|
-
new ProposalNotFoundError(BigInt(1)),
|
|
138
|
-
new TransactionError('test'),
|
|
139
|
-
new DeploymentError('test'),
|
|
140
|
-
new InvalidConfigurationError('test'),
|
|
141
|
-
new NetworkNotConfiguredError(),
|
|
142
|
-
];
|
|
143
|
-
|
|
144
|
-
errors.forEach((error) => {
|
|
145
|
-
expect(error).toBeInstanceOf(GovernorSDKError);
|
|
146
|
-
expect(error).toBeInstanceOf(Error);
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
describe('Error Handling Patterns', () => {
|
|
152
|
-
it('should be catchable by specific type', () => {
|
|
153
|
-
try {
|
|
154
|
-
throw new InsufficientStakeError(BigInt(1000), BigInt(500));
|
|
155
|
-
} catch (error) {
|
|
156
|
-
expect(error).toBeInstanceOf(InsufficientStakeError);
|
|
157
|
-
expect(error).toBeInstanceOf(GovernorSDKError);
|
|
158
|
-
if (error instanceof InsufficientStakeError) {
|
|
159
|
-
expect(error.message).toContain('Insufficient stake');
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
it('should be catchable by base GovernorSDKError type', () => {
|
|
165
|
-
const errors = [
|
|
166
|
-
new InvalidParameterError('test', 'reason'),
|
|
167
|
-
new TransactionError('test'),
|
|
168
|
-
];
|
|
169
|
-
|
|
170
|
-
errors.forEach((error) => {
|
|
171
|
-
try {
|
|
172
|
-
throw error;
|
|
173
|
-
} catch (e) {
|
|
174
|
-
expect(e).toBeInstanceOf(GovernorSDKError);
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
});
|
|
@@ -1,370 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration tests for GovernorAPI
|
|
3
|
-
* Tests SDK logic with mocked providers (no real blockchain)
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
7
|
-
import { createMockProviders, createFailingMockProviders } from '../mocks/providers';
|
|
8
|
-
import type { GovernorProviders } from '../../src/common-types';
|
|
9
|
-
import { VoteChoice, ConfigPresets } from '../../src/types';
|
|
10
|
-
import { TransactionError } from '../../src/errors';
|
|
11
|
-
import * as validators from '../../src/validators';
|
|
12
|
-
|
|
13
|
-
describe('GovernorAPI Integration (Mocked)', () => {
|
|
14
|
-
let mockProviders: GovernorProviders;
|
|
15
|
-
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
mockProviders = createMockProviders();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
describe('Provider Interaction', () => {
|
|
21
|
-
it('should use public data provider to query contract state', async () => {
|
|
22
|
-
const state = await mockProviders.publicDataProvider.queryContractState('mock-address');
|
|
23
|
-
|
|
24
|
-
expect(state).toBeDefined();
|
|
25
|
-
expect(state.governanceConfig).toBeDefined();
|
|
26
|
-
expect(mockProviders.publicDataProvider.queryContractState).toHaveBeenCalledWith('mock-address');
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('should use wallet provider to submit transactions', async () => {
|
|
30
|
-
const mockTx = { data: 'mock-transaction' };
|
|
31
|
-
const result = await mockProviders.walletProvider.submitTransaction(mockTx as any);
|
|
32
|
-
|
|
33
|
-
expect(result.public.txHash).toBe('mock-tx-hash');
|
|
34
|
-
expect(mockProviders.walletProvider.submitTransaction).toHaveBeenCalledWith(mockTx);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('should handle transaction failures', async () => {
|
|
38
|
-
const failingProviders = createFailingMockProviders();
|
|
39
|
-
|
|
40
|
-
await expect(
|
|
41
|
-
failingProviders.walletProvider.submitTransaction({ data: 'mock-tx' } as any)
|
|
42
|
-
).rejects.toThrow('Transaction failed');
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
describe('Configuration Validation', () => {
|
|
47
|
-
it('should validate deployment config before deployment', () => {
|
|
48
|
-
const governanceConfig = ConfigPresets.testing();
|
|
49
|
-
const validConfig = {
|
|
50
|
-
governor: {
|
|
51
|
-
governance: governanceConfig,
|
|
52
|
-
executionDelay: governanceConfig.executionDelay,
|
|
53
|
-
gracePeriod: governanceConfig.gracePeriod,
|
|
54
|
-
maxActiveProposals: BigInt(100),
|
|
55
|
-
proposalLifetime: governanceConfig.proposalLifetime,
|
|
56
|
-
emergencyVetoEnabled: true,
|
|
57
|
-
emergencyVetoThreshold: BigInt(75000),
|
|
58
|
-
},
|
|
59
|
-
token: {
|
|
60
|
-
name: 'Test DAO',
|
|
61
|
-
symbol: 'TDAO',
|
|
62
|
-
decimals: BigInt(18),
|
|
63
|
-
},
|
|
64
|
-
adminKey: new Uint8Array(32),
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
// Should not throw
|
|
68
|
-
expect(() => {
|
|
69
|
-
validators.validateDeploymentConfig(validConfig);
|
|
70
|
-
}).not.toThrow();
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('should reject invalid deployment config', () => {
|
|
74
|
-
const invalidConfig = {
|
|
75
|
-
governor: {
|
|
76
|
-
governance: ConfigPresets.testing(),
|
|
77
|
-
executionDelay: BigInt(60),
|
|
78
|
-
gracePeriod: BigInt(300),
|
|
79
|
-
maxActiveProposals: BigInt(100),
|
|
80
|
-
proposalLifetime: BigInt(86400),
|
|
81
|
-
emergencyVetoEnabled: true,
|
|
82
|
-
emergencyVetoThreshold: BigInt(75000),
|
|
83
|
-
},
|
|
84
|
-
token: {
|
|
85
|
-
name: 'Test DAO',
|
|
86
|
-
symbol: 'TDAO',
|
|
87
|
-
decimals: BigInt(18),
|
|
88
|
-
},
|
|
89
|
-
adminKey: new Uint8Array(16), // Invalid: should be 32 bytes
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
expect(() => {
|
|
93
|
-
validators.validateDeploymentConfig(invalidConfig);
|
|
94
|
-
}).toThrow();
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
describe('Vote Choice Validation', () => {
|
|
99
|
-
it('should accept valid vote choices', () => {
|
|
100
|
-
expect(() => validators.validateVoteChoice(VoteChoice.For)).not.toThrow();
|
|
101
|
-
expect(() => validators.validateVoteChoice(VoteChoice.Against)).not.toThrow();
|
|
102
|
-
expect(() => validators.validateVoteChoice(VoteChoice.Abstain)).not.toThrow();
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('should reject invalid vote choices', () => {
|
|
106
|
-
expect(() => validators.validateVoteChoice(3 as any)).toThrow();
|
|
107
|
-
expect(() => validators.validateVoteChoice(-1 as any)).toThrow();
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
describe('Proposal Validation', () => {
|
|
112
|
-
it('should validate proposal parameters', () => {
|
|
113
|
-
const creator = new Uint8Array(32);
|
|
114
|
-
|
|
115
|
-
expect(() => {
|
|
116
|
-
validators.validateProposal('Valid Title', 'Valid description', creator);
|
|
117
|
-
}).not.toThrow();
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('should reject proposals with empty title', () => {
|
|
121
|
-
const creator = new Uint8Array(32);
|
|
122
|
-
|
|
123
|
-
expect(() => {
|
|
124
|
-
validators.validateProposal('', 'Valid description', creator);
|
|
125
|
-
}).toThrow();
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it('should reject proposals with title too long', () => {
|
|
129
|
-
const creator = new Uint8Array(32);
|
|
130
|
-
|
|
131
|
-
expect(() => {
|
|
132
|
-
validators.validateProposal('a'.repeat(257), 'Valid description', creator);
|
|
133
|
-
}).toThrow();
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it('should reject proposals with empty description', () => {
|
|
137
|
-
const creator = new Uint8Array(32);
|
|
138
|
-
|
|
139
|
-
expect(() => {
|
|
140
|
-
validators.validateProposal('Valid title', '', creator);
|
|
141
|
-
}).toThrow();
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
describe('Transaction Flow', () => {
|
|
146
|
-
it('should balance and submit transaction', async () => {
|
|
147
|
-
const unbalancedTx = { data: 'unbalanced-tx' };
|
|
148
|
-
|
|
149
|
-
// Balance transaction
|
|
150
|
-
const balancedTx = await mockProviders.walletProvider.balanceTransaction(unbalancedTx as any);
|
|
151
|
-
expect(balancedTx).toBeDefined();
|
|
152
|
-
|
|
153
|
-
// Submit transaction
|
|
154
|
-
const result = await mockProviders.walletProvider.submitTransaction(balancedTx);
|
|
155
|
-
|
|
156
|
-
expect(result.public.txHash).toBe('mock-tx-hash');
|
|
157
|
-
expect(mockProviders.walletProvider.balanceTransaction).toHaveBeenCalled();
|
|
158
|
-
expect(mockProviders.walletProvider.submitTransaction).toHaveBeenCalled();
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it('should handle transaction submission errors', async () => {
|
|
162
|
-
const failingProviders = createFailingMockProviders();
|
|
163
|
-
const tx = { data: 'mock-tx' };
|
|
164
|
-
|
|
165
|
-
await expect(
|
|
166
|
-
failingProviders.walletProvider.submitTransaction(tx as any)
|
|
167
|
-
).rejects.toThrow();
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
describe('Private State Management', () => {
|
|
172
|
-
it('should retrieve private state', async () => {
|
|
173
|
-
const stateId = 'governorPrivateState';
|
|
174
|
-
const state = await mockProviders.privateStateProvider.get(stateId);
|
|
175
|
-
|
|
176
|
-
expect(mockProviders.privateStateProvider.get).toHaveBeenCalledWith(stateId);
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
it('should save private state', async () => {
|
|
180
|
-
const stateId = 'governorPrivateState';
|
|
181
|
-
const newState = {
|
|
182
|
-
secretKey: new Uint8Array(32),
|
|
183
|
-
currentTime: BigInt(Math.floor(Date.now() / 1000)),
|
|
184
|
-
userStake: {
|
|
185
|
-
amount: BigInt(100),
|
|
186
|
-
delegatedTo: new Uint8Array(32),
|
|
187
|
-
stakedAt: BigInt(0),
|
|
188
|
-
},
|
|
189
|
-
votingHistory: [],
|
|
190
|
-
proposalHistory: [],
|
|
191
|
-
governanceConfig: ConfigPresets.testing(),
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
await mockProviders.privateStateProvider.set(stateId, newState);
|
|
195
|
-
|
|
196
|
-
expect(mockProviders.privateStateProvider.set).toHaveBeenCalledWith(stateId, newState);
|
|
197
|
-
});
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
describe('Block Height Queries', () => {
|
|
201
|
-
it('should query current block height', async () => {
|
|
202
|
-
const height = await mockProviders.publicDataProvider.getBlockHeight();
|
|
203
|
-
|
|
204
|
-
expect(height).toBe(BigInt(1000));
|
|
205
|
-
expect(mockProviders.publicDataProvider.getBlockHeight).toHaveBeenCalled();
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
describe('Error Handling Scenarios', () => {
|
|
210
|
-
it('should handle wallet connection errors gracefully', async () => {
|
|
211
|
-
const errorProviders = createMockProviders({
|
|
212
|
-
walletProvider: {
|
|
213
|
-
state: async () => {
|
|
214
|
-
throw new Error('Wallet not connected');
|
|
215
|
-
},
|
|
216
|
-
} as any,
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
await expect(errorProviders.walletProvider.state()).rejects.toThrow('Wallet not connected');
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
it('should handle indexer query errors', async () => {
|
|
223
|
-
const errorProviders = createMockProviders({
|
|
224
|
-
publicDataProvider: {
|
|
225
|
-
queryContractState: async () => {
|
|
226
|
-
throw new Error('Indexer unavailable');
|
|
227
|
-
},
|
|
228
|
-
} as any,
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
await expect(
|
|
232
|
-
errorProviders.publicDataProvider.queryContractState('mock-address')
|
|
233
|
-
).rejects.toThrow('Indexer unavailable');
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
it('should handle proof generation errors', async () => {
|
|
237
|
-
const errorProviders = createMockProviders({
|
|
238
|
-
proofProvider: {
|
|
239
|
-
generateProof: async () => {
|
|
240
|
-
throw new Error('Proof generation failed');
|
|
241
|
-
},
|
|
242
|
-
} as any,
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
await expect(
|
|
246
|
-
errorProviders.proofProvider.generateProof({} as any)
|
|
247
|
-
).rejects.toThrow('Proof generation failed');
|
|
248
|
-
});
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
describe('Wallet State', () => {
|
|
252
|
-
it('should retrieve wallet state', async () => {
|
|
253
|
-
const state = await mockProviders.walletProvider.state();
|
|
254
|
-
|
|
255
|
-
expect(state.address).toBe('mock-wallet-address');
|
|
256
|
-
expect(state.coinPublicKey).toBeInstanceOf(Uint8Array);
|
|
257
|
-
expect(state.encryptionPublicKey).toBeInstanceOf(Uint8Array);
|
|
258
|
-
});
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
describe('Configuration Presets', () => {
|
|
262
|
-
it('should provide testing configuration', () => {
|
|
263
|
-
const config = ConfigPresets.testing();
|
|
264
|
-
|
|
265
|
-
expect(config.votingPeriod).toBe(BigInt(300));
|
|
266
|
-
expect(config.quorumThreshold).toBe(BigInt(100));
|
|
267
|
-
expect(config.proposalThreshold).toBe(BigInt(100));
|
|
268
|
-
expect(config.minStakeAmount).toBe(BigInt(10));
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
it('should provide production configuration', () => {
|
|
272
|
-
const config = ConfigPresets.production();
|
|
273
|
-
|
|
274
|
-
expect(config.votingPeriod).toBe(BigInt(604800));
|
|
275
|
-
expect(config.quorumThreshold).toBe(BigInt(100000));
|
|
276
|
-
expect(config.proposalThreshold).toBe(BigInt(50000));
|
|
277
|
-
expect(config.minStakeAmount).toBe(BigInt(1000));
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
it('production config should have higher thresholds than testing', () => {
|
|
281
|
-
const testing = ConfigPresets.testing();
|
|
282
|
-
const production = ConfigPresets.production();
|
|
283
|
-
|
|
284
|
-
expect(production.votingPeriod).toBeGreaterThan(testing.votingPeriod);
|
|
285
|
-
expect(production.quorumThreshold).toBeGreaterThan(testing.quorumThreshold);
|
|
286
|
-
expect(production.proposalThreshold).toBeGreaterThan(testing.proposalThreshold);
|
|
287
|
-
expect(production.minStakeAmount).toBeGreaterThan(testing.minStakeAmount);
|
|
288
|
-
});
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
describe('GovernorAPI Method Calls (Mocked)', () => {
|
|
292
|
-
it('should call publicDataProvider.queryContractState when querying state', async () => {
|
|
293
|
-
const contractAddress = 'test-contract-address';
|
|
294
|
-
const state = await mockProviders.publicDataProvider.queryContractState(contractAddress);
|
|
295
|
-
|
|
296
|
-
expect(mockProviders.publicDataProvider.queryContractState).toHaveBeenCalledWith(contractAddress);
|
|
297
|
-
expect(state.governanceConfig).toBeDefined();
|
|
298
|
-
expect(state.activeProposalCount).toBe(BigInt(0));
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
it('should call walletProvider.balanceTransaction before submission', async () => {
|
|
302
|
-
const unbalancedTx = { data: 'test-transaction' };
|
|
303
|
-
await mockProviders.walletProvider.balanceTransaction(unbalancedTx as any);
|
|
304
|
-
|
|
305
|
-
expect(mockProviders.walletProvider.balanceTransaction).toHaveBeenCalledWith(unbalancedTx);
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
it('should call proofProvider.generateProof for ZK proofs', async () => {
|
|
309
|
-
const proofInput = { witness: 'test-witness' };
|
|
310
|
-
const proof = await mockProviders.proofProvider.generateProof(proofInput as any);
|
|
311
|
-
|
|
312
|
-
expect(mockProviders.proofProvider.generateProof).toHaveBeenCalledWith(proofInput);
|
|
313
|
-
expect(proof.proof).toBeInstanceOf(Uint8Array);
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
it('should retrieve block height from publicDataProvider', async () => {
|
|
317
|
-
const height = await mockProviders.publicDataProvider.getBlockHeight();
|
|
318
|
-
|
|
319
|
-
expect(height).toBe(BigInt(1000));
|
|
320
|
-
expect(mockProviders.publicDataProvider.getBlockHeight).toHaveBeenCalled();
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
it('should handle successful transaction submission', async () => {
|
|
324
|
-
const tx = { data: 'test-tx' };
|
|
325
|
-
const result = await mockProviders.walletProvider.submitTransaction(tx as any);
|
|
326
|
-
|
|
327
|
-
expect(result.public.txHash).toBe('mock-tx-hash');
|
|
328
|
-
expect(result.private.result.success).toBe(true);
|
|
329
|
-
expect(mockProviders.walletProvider.submitTransaction).toHaveBeenCalledWith(tx);
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
it('should handle transaction failure', async () => {
|
|
333
|
-
const failingProviders = createFailingMockProviders();
|
|
334
|
-
const tx = { data: 'failing-tx' };
|
|
335
|
-
|
|
336
|
-
await expect(
|
|
337
|
-
failingProviders.walletProvider.submitTransaction(tx as any)
|
|
338
|
-
).rejects.toThrow('Transaction failed');
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
it('should save and retrieve private state', async () => {
|
|
342
|
-
const stateId = 'test-state';
|
|
343
|
-
const newState = {
|
|
344
|
-
secretKey: new Uint8Array(32),
|
|
345
|
-
currentTime: BigInt(Date.now()),
|
|
346
|
-
userStake: {
|
|
347
|
-
amount: BigInt(100),
|
|
348
|
-
delegatedTo: new Uint8Array(32),
|
|
349
|
-
stakedAt: BigInt(0),
|
|
350
|
-
},
|
|
351
|
-
votingHistory: [],
|
|
352
|
-
proposalHistory: [],
|
|
353
|
-
governanceConfig: ConfigPresets.testing(),
|
|
354
|
-
};
|
|
355
|
-
|
|
356
|
-
await mockProviders.privateStateProvider.set(stateId, newState);
|
|
357
|
-
expect(mockProviders.privateStateProvider.set).toHaveBeenCalledWith(stateId, newState);
|
|
358
|
-
|
|
359
|
-
const retrieved = await mockProviders.privateStateProvider.get(stateId);
|
|
360
|
-
expect(mockProviders.privateStateProvider.get).toHaveBeenCalledWith(stateId);
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
it('should handle network query', async () => {
|
|
364
|
-
const network = await mockProviders.publicDataProvider.queryNetwork();
|
|
365
|
-
|
|
366
|
-
expect(network.networkId).toBe('testnet');
|
|
367
|
-
expect(mockProviders.publicDataProvider.queryNetwork).toHaveBeenCalled();
|
|
368
|
-
});
|
|
369
|
-
});
|
|
370
|
-
});
|
package/test/mocks/providers.ts
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mock providers for integration testing
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { vi } from 'vitest';
|
|
6
|
-
import type { GovernorProviders } from '../../src/common-types';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Creates mock providers for testing SDK logic without real blockchain
|
|
10
|
-
*/
|
|
11
|
-
export function createMockProviders(overrides?: Partial<GovernorProviders>): GovernorProviders {
|
|
12
|
-
const mockContractState = {
|
|
13
|
-
governanceConfig: {
|
|
14
|
-
votingPeriod: BigInt(300),
|
|
15
|
-
quorumThreshold: BigInt(100),
|
|
16
|
-
proposalThreshold: BigInt(100),
|
|
17
|
-
proposalLifetime: BigInt(86400),
|
|
18
|
-
executionDelay: BigInt(60),
|
|
19
|
-
gracePeriod: BigInt(300),
|
|
20
|
-
minStakeAmount: BigInt(10),
|
|
21
|
-
stakingPeriod: BigInt(60),
|
|
22
|
-
},
|
|
23
|
-
activeProposalCount: BigInt(0),
|
|
24
|
-
totalStaked: BigInt(0),
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
privateStateProvider: {
|
|
29
|
-
get: vi.fn().mockResolvedValue(null),
|
|
30
|
-
set: vi.fn().mockResolvedValue(undefined),
|
|
31
|
-
...overrides?.privateStateProvider,
|
|
32
|
-
},
|
|
33
|
-
publicDataProvider: {
|
|
34
|
-
queryContractState: vi.fn().mockResolvedValue(mockContractState),
|
|
35
|
-
getBlockHeight: vi.fn().mockResolvedValue(BigInt(1000)),
|
|
36
|
-
queryNetwork: vi.fn().mockResolvedValue({ networkId: 'testnet' }),
|
|
37
|
-
findDeployedContract: vi.fn(),
|
|
38
|
-
...overrides?.publicDataProvider,
|
|
39
|
-
},
|
|
40
|
-
walletProvider: {
|
|
41
|
-
coinPublicKey: new Uint8Array(32),
|
|
42
|
-
state: vi.fn().mockResolvedValue({
|
|
43
|
-
address: 'mock-wallet-address',
|
|
44
|
-
coinPublicKey: new Uint8Array(32),
|
|
45
|
-
encryptionPublicKey: new Uint8Array(32),
|
|
46
|
-
}),
|
|
47
|
-
balanceTransaction: vi.fn().mockImplementation((unbalanced) => unbalanced),
|
|
48
|
-
submitTransaction: vi.fn().mockResolvedValue({
|
|
49
|
-
public: {
|
|
50
|
-
txHash: 'mock-tx-hash',
|
|
51
|
-
contractAddress: 'mock-contract-address',
|
|
52
|
-
},
|
|
53
|
-
private: {
|
|
54
|
-
result: {
|
|
55
|
-
proposalId: BigInt(1),
|
|
56
|
-
effectId: BigInt(0),
|
|
57
|
-
success: true,
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
}),
|
|
61
|
-
...overrides?.walletProvider,
|
|
62
|
-
},
|
|
63
|
-
proofProvider: {
|
|
64
|
-
generateProof: vi.fn().mockResolvedValue({
|
|
65
|
-
proof: new Uint8Array(100),
|
|
66
|
-
publicInputs: [],
|
|
67
|
-
}),
|
|
68
|
-
...overrides?.proofProvider,
|
|
69
|
-
},
|
|
70
|
-
zkConfigProvider: {
|
|
71
|
-
getZkConfig: vi.fn().mockResolvedValue({
|
|
72
|
-
contractAddress: 'mock-contract-address',
|
|
73
|
-
circuits: {},
|
|
74
|
-
}),
|
|
75
|
-
...overrides?.zkConfigProvider,
|
|
76
|
-
},
|
|
77
|
-
midnightProvider: {
|
|
78
|
-
submitTx: vi.fn().mockResolvedValue('mock-tx-hash'),
|
|
79
|
-
...overrides?.midnightProvider,
|
|
80
|
-
},
|
|
81
|
-
...overrides,
|
|
82
|
-
} as unknown as GovernorProviders;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Creates mock providers that simulate transaction failure
|
|
87
|
-
*/
|
|
88
|
-
export function createFailingMockProviders(): GovernorProviders {
|
|
89
|
-
return createMockProviders({
|
|
90
|
-
walletProvider: {
|
|
91
|
-
coinPublicKey: new Uint8Array(32),
|
|
92
|
-
state: vi.fn().mockResolvedValue({
|
|
93
|
-
address: 'mock-wallet-address',
|
|
94
|
-
coinPublicKey: new Uint8Array(32),
|
|
95
|
-
encryptionPublicKey: new Uint8Array(32),
|
|
96
|
-
}),
|
|
97
|
-
balanceTransaction: vi.fn().mockImplementation((unbalanced) => unbalanced),
|
|
98
|
-
submitTransaction: vi.fn().mockRejectedValue(new Error('Transaction failed')),
|
|
99
|
-
} as any,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Creates mock providers that simulate insufficient stake
|
|
105
|
-
*/
|
|
106
|
-
export function createInsufficientStakeMockProviders(): GovernorProviders {
|
|
107
|
-
return createMockProviders({
|
|
108
|
-
publicDataProvider: {
|
|
109
|
-
queryContractState: vi.fn().mockResolvedValue({
|
|
110
|
-
governanceConfig: {
|
|
111
|
-
votingPeriod: BigInt(300),
|
|
112
|
-
quorumThreshold: BigInt(100),
|
|
113
|
-
proposalThreshold: BigInt(100),
|
|
114
|
-
proposalLifetime: BigInt(86400),
|
|
115
|
-
executionDelay: BigInt(60),
|
|
116
|
-
gracePeriod: BigInt(300),
|
|
117
|
-
minStakeAmount: BigInt(10),
|
|
118
|
-
stakingPeriod: BigInt(60),
|
|
119
|
-
},
|
|
120
|
-
stakes: {
|
|
121
|
-
// User has insufficient stake
|
|
122
|
-
'mock-user': { amount: BigInt(5), delegatedTo: new Uint8Array(32), stakedAt: BigInt(0) },
|
|
123
|
-
},
|
|
124
|
-
}),
|
|
125
|
-
getBlockHeight: vi.fn().mockResolvedValue(BigInt(1000)),
|
|
126
|
-
queryNetwork: vi.fn().mockResolvedValue({ networkId: 'testnet' }),
|
|
127
|
-
findDeployedContract: vi.fn(),
|
|
128
|
-
} as any,
|
|
129
|
-
});
|
|
130
|
-
}
|