@solana/keychain-para 0.0.0 → 0.5.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 +123 -0
- package/dist/__tests__/para-signer.integration.test.d.ts +2 -0
- package/dist/__tests__/para-signer.integration.test.d.ts.map +1 -0
- package/dist/__tests__/para-signer.integration.test.js +17 -0
- package/dist/__tests__/para-signer.integration.test.js.map +1 -0
- package/dist/__tests__/para-signer.test.d.ts +2 -0
- package/dist/__tests__/para-signer.test.d.ts.map +1 -0
- package/dist/__tests__/para-signer.test.js +362 -0
- package/dist/__tests__/para-signer.test.js.map +1 -0
- package/dist/__tests__/setup.d.ts +4 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +19 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/para-signer.d.ts +66 -0
- package/dist/para-signer.d.ts.map +1 -0
- package/dist/para-signer.js +268 -0
- package/dist/para-signer.js.map +1 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +52 -8
- package/src/__tests__/para-signer.integration.test.ts +17 -0
- package/src/__tests__/para-signer.test.ts +487 -0
- package/src/__tests__/setup.ts +24 -0
- package/src/index.ts +4 -0
- package/src/para-signer.ts +328 -0
- package/src/types.ts +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# @solana/keychain-para
|
|
2
|
+
|
|
3
|
+
Para MPC signer for Solana transactions using Para's REST API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @solana/keychain-para
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
1. A [Para](https://getpara.com) account with API access
|
|
14
|
+
2. A Para secret API key (server-side only, starts with `sk_`)
|
|
15
|
+
3. A Solana wallet created via the [Para REST API](https://docs.getpara.com/v2/rest/wallets/create-wallet) or dashboard
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Create and Initialize
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { createParaSigner } from '@solana/keychain-para';
|
|
23
|
+
|
|
24
|
+
// Create and initialize the signer (fetches public key from Para API)
|
|
25
|
+
const signer = await createParaSigner({
|
|
26
|
+
apiKey: 'your-para-secret-key',
|
|
27
|
+
walletId: 'your-para-wallet-id',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
console.log('Signer address:', signer.address);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Sign Messages
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { createSignableMessage } from '@solana/signers';
|
|
37
|
+
|
|
38
|
+
const message = createSignableMessage('Hello, Para!');
|
|
39
|
+
const [signatures] = await signer.signMessages([message]);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Sign Transactions
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// Sign transactions using Para's API
|
|
46
|
+
const [signatures] = await signer.signTransactions([transaction]);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Check Availability
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
const available = await signer.isAvailable();
|
|
53
|
+
console.log('Para wallet available:', available);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### With Rate Limiting
|
|
57
|
+
|
|
58
|
+
If you're signing multiple transactions/messages concurrently and want to avoid rate limits:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
const signer = await createParaSigner({
|
|
62
|
+
apiKey: 'your-para-secret-key',
|
|
63
|
+
walletId: 'your-para-wallet-id',
|
|
64
|
+
requestDelayMs: 100, // 100ms delay between concurrent requests
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Configuration
|
|
69
|
+
|
|
70
|
+
### ParaSignerConfig
|
|
71
|
+
|
|
72
|
+
| Field | Type | Required | Description |
|
|
73
|
+
|-------|------|----------|-------------|
|
|
74
|
+
| `apiKey` | `string` | Yes | Your Para secret API key (starts with `sk_`) |
|
|
75
|
+
| `walletId` | `string` | Yes | The Para wallet UUID to use for signing |
|
|
76
|
+
| `apiBaseUrl` | `string` | No | Custom API base URL (default: `https://api.getpara.com`) |
|
|
77
|
+
| `requestDelayMs` | `number` | No | Delay in ms between concurrent signing requests (default: 0) |
|
|
78
|
+
|
|
79
|
+
## How It Works
|
|
80
|
+
|
|
81
|
+
1. **Initialization**: Fetches the wallet's public key from Para's REST API during creation
|
|
82
|
+
2. **Signing**: Sends raw bytes (hex-encoded) to Para's `/v1/wallets/:walletId/sign-raw` endpoint
|
|
83
|
+
3. **Response**: Decodes the hex-encoded Ed25519 signature from Para's response
|
|
84
|
+
|
|
85
|
+
Para uses MPC (Multi-Party Computation) for key management — private keys are never assembled in a single location.
|
|
86
|
+
|
|
87
|
+
## Error Handling
|
|
88
|
+
|
|
89
|
+
The signer will throw errors with specific codes from `@solana/keychain-core`:
|
|
90
|
+
|
|
91
|
+
- `CONFIG_ERROR` - Invalid configuration (missing apiKey or walletId)
|
|
92
|
+
- `HTTP_ERROR` - Network request failed
|
|
93
|
+
- `REMOTE_API_ERROR` - Para API returned an error
|
|
94
|
+
- `PARSING_ERROR` - Failed to parse Para response
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { SignerErrorCode } from '@solana/keychain-core';
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
await signer.signMessages([message]);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
if (error.code === SignerErrorCode.REMOTE_API_ERROR) {
|
|
103
|
+
console.error('Para API error:', error.message);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Security Notes
|
|
109
|
+
|
|
110
|
+
- Store your secret key securely (use environment variables)
|
|
111
|
+
- Never expose your secret key in client-side code — it starts with `sk_` for a reason
|
|
112
|
+
- This signer is intended for server-side use or secure environments
|
|
113
|
+
- Para handles key management via MPC — your private keys never leave Para's infrastructure
|
|
114
|
+
|
|
115
|
+
## Resources
|
|
116
|
+
|
|
117
|
+
- [Para REST API Documentation](https://docs.getpara.com/v2/rest/overview)
|
|
118
|
+
- [Create a Wallet](https://docs.getpara.com/v2/rest/wallets/create-wallet)
|
|
119
|
+
- [Sign Raw Data](https://docs.getpara.com/v2/rest/wallets/sign-raw)
|
|
120
|
+
|
|
121
|
+
## License
|
|
122
|
+
|
|
123
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"para-signer.integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/para-signer.integration.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, it } from 'vitest';
|
|
2
|
+
import { runSignerIntegrationTest } from '@solana/keychain-test-utils';
|
|
3
|
+
import { getConfig } from './setup';
|
|
4
|
+
import { config } from 'dotenv';
|
|
5
|
+
config();
|
|
6
|
+
describe('ParaSigner Integration', () => {
|
|
7
|
+
it.skipIf(!process.env.PARA_API_KEY)('signs transactions with real API', async () => {
|
|
8
|
+
await runSignerIntegrationTest(await getConfig(['signTransaction']));
|
|
9
|
+
});
|
|
10
|
+
it.skipIf(!process.env.PARA_API_KEY)('signs messages with real API', async () => {
|
|
11
|
+
await runSignerIntegrationTest(await getConfig(['signMessage']));
|
|
12
|
+
});
|
|
13
|
+
it.skipIf(!process.env.PARA_API_KEY)('simulates transactions with real API', async () => {
|
|
14
|
+
await runSignerIntegrationTest(await getConfig(['simulateTransaction']));
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=para-signer.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"para-signer.integration.test.js","sourceRoot":"","sources":["../../src/__tests__/para-signer.integration.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,MAAM,EAAE,CAAC;AAET,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChF,MAAM,wBAAwB,CAAC,MAAM,SAAS,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,wBAAwB,CAAC,MAAM,SAAS,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpF,MAAM,wBAAwB,CAAC,MAAM,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"para-signer.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/para-signer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { assertIsSolanaSigner } from '@solana/keychain-core';
|
|
3
|
+
import { ParaSigner } from '../para-signer.js';
|
|
4
|
+
// Mock fetch globally
|
|
5
|
+
global.fetch = vi.fn();
|
|
6
|
+
// Valid 64-byte Ed25519 signature as 128 hex chars
|
|
7
|
+
const MOCK_SIGNATURE = 'ab'.repeat(64);
|
|
8
|
+
const MOCK_ADDRESS = '11111111111111111111111111111111';
|
|
9
|
+
const mockConfig = {
|
|
10
|
+
apiKey: 'sk_test_api_key',
|
|
11
|
+
apiBaseUrl: 'https://api.test.getpara.com',
|
|
12
|
+
walletId: '00000000-0000-0000-0000-000000000000',
|
|
13
|
+
};
|
|
14
|
+
function mockWalletResponse(overrides) {
|
|
15
|
+
return new Response(JSON.stringify({
|
|
16
|
+
address: MOCK_ADDRESS,
|
|
17
|
+
id: '00000000-0000-0000-0000-000000000000',
|
|
18
|
+
publicKey: MOCK_ADDRESS,
|
|
19
|
+
status: 'ready',
|
|
20
|
+
type: 'SOLANA',
|
|
21
|
+
...overrides,
|
|
22
|
+
}), { status: 200 });
|
|
23
|
+
}
|
|
24
|
+
function mockSignResponse(signature = MOCK_SIGNATURE) {
|
|
25
|
+
return new Response(JSON.stringify({ signature }), { status: 200 });
|
|
26
|
+
}
|
|
27
|
+
describe('ParaSigner', () => {
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
vi.resetAllMocks();
|
|
30
|
+
});
|
|
31
|
+
describe('create', () => {
|
|
32
|
+
it('should create a signer by fetching wallet address', async () => {
|
|
33
|
+
vi.mocked(fetch).mockResolvedValueOnce(mockWalletResponse());
|
|
34
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
35
|
+
expect(signer.address).toBe(MOCK_ADDRESS);
|
|
36
|
+
expect(fetch).toHaveBeenCalledWith('https://api.test.getpara.com/v1/wallets/00000000-0000-0000-0000-000000000000', expect.objectContaining({
|
|
37
|
+
headers: { 'X-API-Key': 'sk_test_api_key' },
|
|
38
|
+
method: 'GET',
|
|
39
|
+
}));
|
|
40
|
+
});
|
|
41
|
+
it('should satisfy the SolanaSigner interface', async () => {
|
|
42
|
+
vi.mocked(fetch).mockResolvedValueOnce(mockWalletResponse());
|
|
43
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
44
|
+
assertIsSolanaSigner(signer);
|
|
45
|
+
});
|
|
46
|
+
it('should throw CONFIG_ERROR for missing apiKey', async () => {
|
|
47
|
+
await expect(ParaSigner.create({ ...mockConfig, apiKey: '' })).rejects.toMatchObject({
|
|
48
|
+
code: 'SIGNER_CONFIG_ERROR',
|
|
49
|
+
message: expect.stringContaining('Missing required configuration fields'),
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
it('should throw CONFIG_ERROR for missing walletId', async () => {
|
|
53
|
+
await expect(ParaSigner.create({ ...mockConfig, walletId: '' })).rejects.toMatchObject({
|
|
54
|
+
code: 'SIGNER_CONFIG_ERROR',
|
|
55
|
+
message: expect.stringContaining('Missing required configuration fields'),
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
it('should throw CONFIG_ERROR for non-sk_ apiKey', async () => {
|
|
59
|
+
await expect(ParaSigner.create({ ...mockConfig, apiKey: 'pk_test_key' })).rejects.toMatchObject({
|
|
60
|
+
code: 'SIGNER_CONFIG_ERROR',
|
|
61
|
+
message: expect.stringContaining('apiKey must be a Para secret key'),
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
it('should throw CONFIG_ERROR for non-UUID walletId', async () => {
|
|
65
|
+
await expect(ParaSigner.create({ ...mockConfig, walletId: 'not-a-uuid' })).rejects.toMatchObject({
|
|
66
|
+
code: 'SIGNER_CONFIG_ERROR',
|
|
67
|
+
message: expect.stringContaining('walletId must be a valid UUID'),
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
it('should throw CONFIG_ERROR for non-HTTPS apiBaseUrl', async () => {
|
|
71
|
+
await expect(ParaSigner.create({ ...mockConfig, apiBaseUrl: 'http://api.getpara.com' })).rejects.toMatchObject({
|
|
72
|
+
code: 'SIGNER_CONFIG_ERROR',
|
|
73
|
+
message: expect.stringContaining('apiBaseUrl must use HTTPS'),
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
it('should throw CONFIG_ERROR for invalid apiBaseUrl', async () => {
|
|
77
|
+
await expect(ParaSigner.create({ ...mockConfig, apiBaseUrl: 'not-a-url' })).rejects.toMatchObject({
|
|
78
|
+
code: 'SIGNER_CONFIG_ERROR',
|
|
79
|
+
message: expect.stringContaining('apiBaseUrl is not a valid URL'),
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
it('should throw CONFIG_ERROR for non-SOLANA wallet type', async () => {
|
|
83
|
+
vi.mocked(fetch).mockResolvedValueOnce(mockWalletResponse({ type: 'EVM' }));
|
|
84
|
+
await expect(ParaSigner.create(mockConfig)).rejects.toMatchObject({
|
|
85
|
+
code: 'SIGNER_CONFIG_ERROR',
|
|
86
|
+
message: expect.stringContaining('Expected SOLANA wallet but got EVM'),
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
it('should throw REMOTE_API_ERROR when wallet has no address', async () => {
|
|
90
|
+
vi.mocked(fetch).mockResolvedValueOnce(mockWalletResponse({ address: null }));
|
|
91
|
+
await expect(ParaSigner.create(mockConfig)).rejects.toMatchObject({
|
|
92
|
+
code: 'SIGNER_REMOTE_API_ERROR',
|
|
93
|
+
message: expect.stringContaining('does not have an address'),
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
it('should throw REMOTE_API_ERROR when API returns error', async () => {
|
|
97
|
+
vi.mocked(fetch).mockResolvedValueOnce(new Response(JSON.stringify({ message: 'Unauthorized' }), { status: 401 }));
|
|
98
|
+
await expect(ParaSigner.create(mockConfig)).rejects.toMatchObject({
|
|
99
|
+
code: 'SIGNER_REMOTE_API_ERROR',
|
|
100
|
+
message: expect.stringContaining('Failed to fetch wallet'),
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
it('should throw HTTP_ERROR when network fails', async () => {
|
|
104
|
+
vi.mocked(fetch).mockRejectedValueOnce(new Error('Network error'));
|
|
105
|
+
await expect(ParaSigner.create(mockConfig)).rejects.toMatchObject({
|
|
106
|
+
code: 'SIGNER_HTTP_ERROR',
|
|
107
|
+
message: expect.stringContaining('Para network request failed'),
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
it('should remove trailing slash from apiBaseUrl', async () => {
|
|
111
|
+
vi.mocked(fetch).mockResolvedValueOnce(mockWalletResponse());
|
|
112
|
+
await ParaSigner.create({ ...mockConfig, apiBaseUrl: 'https://api.test.getpara.com/' });
|
|
113
|
+
expect(fetch).toHaveBeenCalledWith('https://api.test.getpara.com/v1/wallets/00000000-0000-0000-0000-000000000000', expect.anything());
|
|
114
|
+
});
|
|
115
|
+
it('should throw CONFIG_ERROR for negative requestDelayMs', async () => {
|
|
116
|
+
vi.mocked(fetch).mockResolvedValueOnce(mockWalletResponse());
|
|
117
|
+
await expect(ParaSigner.create({ ...mockConfig, requestDelayMs: -1 })).rejects.toMatchObject({
|
|
118
|
+
code: 'SIGNER_CONFIG_ERROR',
|
|
119
|
+
message: expect.stringContaining('requestDelayMs must not be negative'),
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
it('should warn for high requestDelayMs', async () => {
|
|
123
|
+
vi.mocked(fetch).mockResolvedValueOnce(mockWalletResponse());
|
|
124
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => { });
|
|
125
|
+
await ParaSigner.create({ ...mockConfig, requestDelayMs: 3001 });
|
|
126
|
+
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('requestDelayMs is greater than 3000ms'));
|
|
127
|
+
warnSpy.mockRestore();
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
describe('isAvailable', () => {
|
|
131
|
+
it('should return true when wallet is ready', async () => {
|
|
132
|
+
vi.mocked(fetch)
|
|
133
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
134
|
+
.mockResolvedValueOnce(mockWalletResponse({ status: 'ready' })); // isAvailable
|
|
135
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
136
|
+
const result = await signer.isAvailable();
|
|
137
|
+
expect(result).toBe(true);
|
|
138
|
+
});
|
|
139
|
+
it('should return true when wallet status is ACTIVE', async () => {
|
|
140
|
+
vi.mocked(fetch)
|
|
141
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
142
|
+
.mockResolvedValueOnce(mockWalletResponse({ status: 'ACTIVE' })); // isAvailable
|
|
143
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
144
|
+
const result = await signer.isAvailable();
|
|
145
|
+
expect(result).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
it('should return true when wallet status is mixed case', async () => {
|
|
148
|
+
vi.mocked(fetch)
|
|
149
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
150
|
+
.mockResolvedValueOnce(mockWalletResponse({ status: 'Ready' })); // isAvailable
|
|
151
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
152
|
+
const result = await signer.isAvailable();
|
|
153
|
+
expect(result).toBe(true);
|
|
154
|
+
});
|
|
155
|
+
it('should return false when wallet is not ready', async () => {
|
|
156
|
+
vi.mocked(fetch)
|
|
157
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
158
|
+
.mockResolvedValueOnce(mockWalletResponse({ status: 'creating' })); // isAvailable
|
|
159
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
160
|
+
const result = await signer.isAvailable();
|
|
161
|
+
expect(result).toBe(false);
|
|
162
|
+
});
|
|
163
|
+
it('should return false when wallet type is not SOLANA', async () => {
|
|
164
|
+
vi.mocked(fetch)
|
|
165
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
166
|
+
.mockResolvedValueOnce(mockWalletResponse({ type: 'EVM', status: 'ready' })); // isAvailable
|
|
167
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
168
|
+
const result = await signer.isAvailable();
|
|
169
|
+
expect(result).toBe(false);
|
|
170
|
+
});
|
|
171
|
+
it('should return false when API returns error', async () => {
|
|
172
|
+
vi.mocked(fetch)
|
|
173
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
174
|
+
.mockResolvedValueOnce(new Response('', { status: 500 })); // isAvailable
|
|
175
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
176
|
+
const result = await signer.isAvailable();
|
|
177
|
+
expect(result).toBe(false);
|
|
178
|
+
});
|
|
179
|
+
it('should return false when network fails', async () => {
|
|
180
|
+
vi.mocked(fetch)
|
|
181
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
182
|
+
.mockRejectedValueOnce(new Error('Network error')); // isAvailable
|
|
183
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
184
|
+
const result = await signer.isAvailable();
|
|
185
|
+
expect(result).toBe(false);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
describe('signMessages', () => {
|
|
189
|
+
it('should sign a message successfully', async () => {
|
|
190
|
+
vi.mocked(fetch)
|
|
191
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
192
|
+
.mockResolvedValueOnce(mockSignResponse()); // sign
|
|
193
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
194
|
+
const message = {
|
|
195
|
+
content: new Uint8Array([1, 2, 3, 4]),
|
|
196
|
+
signatures: {},
|
|
197
|
+
};
|
|
198
|
+
const [result] = await signer.signMessages([message]);
|
|
199
|
+
expect(result).toHaveProperty(MOCK_ADDRESS);
|
|
200
|
+
expect(fetch).toHaveBeenLastCalledWith('https://api.test.getpara.com/v1/wallets/00000000-0000-0000-0000-000000000000/sign-raw', expect.objectContaining({
|
|
201
|
+
body: JSON.stringify({ data: '01020304', encoding: 'hex' }),
|
|
202
|
+
headers: {
|
|
203
|
+
'Content-Type': 'application/json',
|
|
204
|
+
'X-API-Key': 'sk_test_api_key',
|
|
205
|
+
},
|
|
206
|
+
method: 'POST',
|
|
207
|
+
}));
|
|
208
|
+
});
|
|
209
|
+
it('should return empty array for empty input', async () => {
|
|
210
|
+
vi.mocked(fetch).mockResolvedValueOnce(mockWalletResponse());
|
|
211
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
212
|
+
const result = await signer.signMessages([]);
|
|
213
|
+
expect(result).toEqual([]);
|
|
214
|
+
});
|
|
215
|
+
it('should handle 0x-prefixed signatures', async () => {
|
|
216
|
+
vi.mocked(fetch)
|
|
217
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
218
|
+
.mockResolvedValueOnce(mockSignResponse('0x' + MOCK_SIGNATURE)); // sign
|
|
219
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
220
|
+
const message = { content: new Uint8Array([1, 2, 3, 4]), signatures: {} };
|
|
221
|
+
const [result] = await signer.signMessages([message]);
|
|
222
|
+
expect(result).toHaveProperty(MOCK_ADDRESS);
|
|
223
|
+
});
|
|
224
|
+
it('should throw REMOTE_API_ERROR on API error', async () => {
|
|
225
|
+
vi.mocked(fetch)
|
|
226
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
227
|
+
.mockResolvedValueOnce(new Response(JSON.stringify({ message: 'rate limited' }), { status: 429 }));
|
|
228
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
229
|
+
const message = { content: new Uint8Array([1, 2, 3, 4]), signatures: {} };
|
|
230
|
+
await expect(signer.signMessages([message])).rejects.toMatchObject({
|
|
231
|
+
code: 'SIGNER_REMOTE_API_ERROR',
|
|
232
|
+
message: expect.stringContaining('Para signing failed'),
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
it('should throw HTTP_ERROR on network failure', async () => {
|
|
236
|
+
vi.mocked(fetch)
|
|
237
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
238
|
+
.mockRejectedValueOnce(new Error('Network failure'));
|
|
239
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
240
|
+
const message = { content: new Uint8Array([1, 2, 3, 4]), signatures: {} };
|
|
241
|
+
await expect(signer.signMessages([message])).rejects.toMatchObject({
|
|
242
|
+
code: 'SIGNER_HTTP_ERROR',
|
|
243
|
+
message: expect.stringContaining('Para network request failed'),
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
it('should throw REMOTE_API_ERROR for missing signature', async () => {
|
|
247
|
+
vi.mocked(fetch)
|
|
248
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
249
|
+
.mockResolvedValueOnce(new Response(JSON.stringify({}), { status: 200 }));
|
|
250
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
251
|
+
const message = { content: new Uint8Array([1, 2, 3, 4]), signatures: {} };
|
|
252
|
+
await expect(signer.signMessages([message])).rejects.toMatchObject({
|
|
253
|
+
code: 'SIGNER_REMOTE_API_ERROR',
|
|
254
|
+
message: expect.stringContaining('Missing signature in Para response'),
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
it('should throw PARSING_ERROR for invalid signature length', async () => {
|
|
258
|
+
vi.mocked(fetch)
|
|
259
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
260
|
+
.mockResolvedValueOnce(mockSignResponse('aabb')); // too short
|
|
261
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
262
|
+
const message = { content: new Uint8Array([1, 2, 3, 4]), signatures: {} };
|
|
263
|
+
await expect(signer.signMessages([message])).rejects.toMatchObject({
|
|
264
|
+
code: 'SIGNER_PARSING_ERROR',
|
|
265
|
+
message: expect.stringContaining('Invalid Ed25519 signature length'),
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
it('should throw PARSING_ERROR for non-hex characters in signature', async () => {
|
|
269
|
+
vi.mocked(fetch)
|
|
270
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
271
|
+
.mockResolvedValueOnce(mockSignResponse('zz'.repeat(64))); // invalid hex
|
|
272
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
273
|
+
const message = { content: new Uint8Array([1, 2, 3, 4]), signatures: {} };
|
|
274
|
+
await expect(signer.signMessages([message])).rejects.toMatchObject({
|
|
275
|
+
code: 'SIGNER_PARSING_ERROR',
|
|
276
|
+
message: expect.stringContaining('Invalid hex characters'),
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
it('should apply request delay for multiple messages', async () => {
|
|
280
|
+
vi.mocked(fetch)
|
|
281
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
282
|
+
.mockResolvedValueOnce(mockSignResponse()) // sign 1
|
|
283
|
+
.mockResolvedValueOnce(mockSignResponse()) // sign 2
|
|
284
|
+
.mockResolvedValueOnce(mockSignResponse()); // sign 3
|
|
285
|
+
const delaySpy = vi.spyOn(global, 'setTimeout');
|
|
286
|
+
const signer = await ParaSigner.create({ ...mockConfig, requestDelayMs: 100 });
|
|
287
|
+
const messages = [
|
|
288
|
+
{ content: new Uint8Array([1, 2, 3, 4]), signatures: {} },
|
|
289
|
+
{ content: new Uint8Array([5, 6, 7, 8]), signatures: {} },
|
|
290
|
+
{ content: new Uint8Array([9, 10, 11, 12]), signatures: {} },
|
|
291
|
+
];
|
|
292
|
+
await signer.signMessages(messages);
|
|
293
|
+
// First message has no delay, second has 100ms, third has 200ms
|
|
294
|
+
expect(delaySpy).toHaveBeenCalledTimes(2);
|
|
295
|
+
expect(delaySpy).toHaveBeenNthCalledWith(1, expect.any(Function), 100);
|
|
296
|
+
expect(delaySpy).toHaveBeenNthCalledWith(2, expect.any(Function), 200);
|
|
297
|
+
delaySpy.mockRestore();
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
describe('signTransactions', () => {
|
|
301
|
+
it('should sign a transaction successfully', async () => {
|
|
302
|
+
vi.mocked(fetch)
|
|
303
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
304
|
+
.mockResolvedValueOnce(mockSignResponse()); // sign
|
|
305
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
306
|
+
const mockTransaction = {
|
|
307
|
+
messageBytes: new Uint8Array([1, 2, 3, 4]),
|
|
308
|
+
signatures: {},
|
|
309
|
+
};
|
|
310
|
+
const [result] = await signer.signTransactions([mockTransaction]);
|
|
311
|
+
expect(result).toHaveProperty(MOCK_ADDRESS);
|
|
312
|
+
expect(fetch).toHaveBeenLastCalledWith('https://api.test.getpara.com/v1/wallets/00000000-0000-0000-0000-000000000000/sign-raw', expect.objectContaining({
|
|
313
|
+
body: JSON.stringify({ data: '01020304', encoding: 'hex' }),
|
|
314
|
+
method: 'POST',
|
|
315
|
+
}));
|
|
316
|
+
});
|
|
317
|
+
it('should return empty array for empty input', async () => {
|
|
318
|
+
vi.mocked(fetch).mockResolvedValueOnce(mockWalletResponse());
|
|
319
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
320
|
+
const result = await signer.signTransactions([]);
|
|
321
|
+
expect(result).toEqual([]);
|
|
322
|
+
});
|
|
323
|
+
it('should sign multiple transactions', async () => {
|
|
324
|
+
vi.mocked(fetch)
|
|
325
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
326
|
+
.mockResolvedValueOnce(mockSignResponse()) // sign 1
|
|
327
|
+
.mockResolvedValueOnce(mockSignResponse()); // sign 2
|
|
328
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
329
|
+
const transactions = [
|
|
330
|
+
{ messageBytes: new Uint8Array([1, 2]), signatures: {} },
|
|
331
|
+
{ messageBytes: new Uint8Array([3, 4]), signatures: {} },
|
|
332
|
+
];
|
|
333
|
+
const results = await signer.signTransactions(transactions);
|
|
334
|
+
expect(results).toHaveLength(2);
|
|
335
|
+
expect(results[0]).toHaveProperty(MOCK_ADDRESS);
|
|
336
|
+
expect(results[1]).toHaveProperty(MOCK_ADDRESS);
|
|
337
|
+
});
|
|
338
|
+
it('should throw REMOTE_API_ERROR on API error', async () => {
|
|
339
|
+
vi.mocked(fetch)
|
|
340
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
341
|
+
.mockResolvedValueOnce(new Response(JSON.stringify({ message: 'rate limited' }), { status: 429 }));
|
|
342
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
343
|
+
const mockTransaction = { messageBytes: new Uint8Array([1, 2, 3, 4]), signatures: {} };
|
|
344
|
+
await expect(signer.signTransactions([mockTransaction])).rejects.toMatchObject({
|
|
345
|
+
code: 'SIGNER_REMOTE_API_ERROR',
|
|
346
|
+
message: expect.stringContaining('Para signing failed'),
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
it('should throw HTTP_ERROR on network failure', async () => {
|
|
350
|
+
vi.mocked(fetch)
|
|
351
|
+
.mockResolvedValueOnce(mockWalletResponse()) // create
|
|
352
|
+
.mockRejectedValueOnce(new Error('Network failure'));
|
|
353
|
+
const signer = await ParaSigner.create(mockConfig);
|
|
354
|
+
const mockTransaction = { messageBytes: new Uint8Array([1, 2, 3, 4]), signatures: {} };
|
|
355
|
+
await expect(signer.signTransactions([mockTransaction])).rejects.toMatchObject({
|
|
356
|
+
code: 'SIGNER_HTTP_ERROR',
|
|
357
|
+
message: expect.stringContaining('Para network request failed'),
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
//# sourceMappingURL=para-signer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"para-signer.test.js","sourceRoot":"","sources":["../../src/__tests__/para-signer.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,sBAAsB;AACtB,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AAEvB,mDAAmD;AACnD,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEvC,MAAM,YAAY,GAAG,kCAAkC,CAAC;AAExD,MAAM,UAAU,GAAG;IACf,MAAM,EAAE,iBAAiB;IACzB,UAAU,EAAE,8BAA8B;IAC1C,QAAQ,EAAE,sCAAsC;CACnD,CAAC;AAEF,SAAS,kBAAkB,CAAC,SAAmC;IAC3D,OAAO,IAAI,QAAQ,CACf,IAAI,CAAC,SAAS,CAAC;QACX,OAAO,EAAE,YAAY;QACrB,EAAE,EAAE,sCAAsC;QAC1C,SAAS,EAAE,YAAY;QACvB,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,QAAQ;QACd,GAAG,SAAS;KACf,CAAC,EACF,EAAE,MAAM,EAAE,GAAG,EAAE,CAClB,CAAC;AACN,CAAC;AAED,SAAS,gBAAgB,CAAC,SAAS,GAAG,cAAc;IAChD,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IACxB,UAAU,CAAC,GAAG,EAAE;QACZ,EAAE,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YAC/D,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAE7D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAEnD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAC9B,8EAA8E,EAC9E,MAAM,CAAC,gBAAgB,CAAC;gBACpB,OAAO,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE;gBAC3C,MAAM,EAAE,KAAK;aAChB,CAAC,CACL,CAAC;QACN,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YACvD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAE7D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAEnD,oBAAoB,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;YAC1D,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBACjF,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,uCAAuC,CAAC;aAC5E,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC5D,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBACnF,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,uCAAuC,CAAC;aAC5E,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;YAC1D,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC5F,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,kCAAkC,CAAC;aACvE,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC7D,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC7F,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,+BAA+B,CAAC;aACpE,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;YAChE,MAAM,MAAM,CACR,UAAU,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,UAAU,EAAE,wBAAwB,EAAE,CAAC,CAC7E,CAAC,OAAO,CAAC,aAAa,CAAC;gBACpB,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,2BAA2B,CAAC;aAChE,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC9F,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,+BAA+B,CAAC;aACpE,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;YAClE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;YAE5E,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC9D,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,oCAAoC,CAAC;aACzE,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;YACtE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAE9E,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC9D,IAAI,EAAE,yBAAyB;gBAC/B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,0BAA0B,CAAC;aAC/D,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;YAClE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAClC,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAC7E,CAAC;YAEF,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC9D,IAAI,EAAE,yBAAyB;gBAC/B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,wBAAwB,CAAC;aAC7D,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YACxD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;YAEnE,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC9D,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,6BAA6B,CAAC;aAClE,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;YAC1D,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAE7D,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,UAAU,EAAE,+BAA+B,EAAE,CAAC,CAAC;YAExF,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAC9B,8EAA8E,EAC9E,MAAM,CAAC,QAAQ,EAAE,CACpB,CAAC;QACN,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;YACnE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAE7D,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBACzF,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,qCAAqC,CAAC;aAC1E,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;YACjD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAC7D,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAEvE,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;YAEjE,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,gBAAgB,CAAC,uCAAuC,CAAC,CAAC,CAAC;YACvG,OAAO,CAAC,WAAW,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QACzB,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;YACrD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc;YAEnF,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC7D,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc;YAEpF,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACjE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc;YAEnF,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;YAC1D,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc;YAEtF,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;YAChE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc;YAEhG,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YACxD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,IAAI,QAAQ,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc;YAE7E,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACpD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,cAAc;YAEtE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;YAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;YAChD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,OAAO;YAEvD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG;gBACZ,OAAO,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBACrC,UAAU,EAAE,EAAE;aACjB,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YAEtD,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;YAC5C,MAAM,CAAC,KAAK,CAAC,CAAC,wBAAwB,CAClC,uFAAuF,EACvF,MAAM,CAAC,gBAAgB,CAAC;gBACpB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;gBAC3D,OAAO,EAAE;oBACL,cAAc,EAAE,kBAAkB;oBAClC,WAAW,EAAE,iBAAiB;iBACjC;gBACD,MAAM,EAAE,MAAM;aACjB,CAAC,CACL,CAAC;QACN,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YACvD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAE7D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YAE7C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YAClD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,gBAAgB,CAAC,IAAI,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO;YAE5E,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;YAE1E,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YAEtD,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YACxD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YAEvG,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;YAE1E,MAAM,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC/D,IAAI,EAAE,yBAAyB;gBAC/B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,CAAC;aAC1D,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YACxD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAEzD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;YAE1E,MAAM,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC/D,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,6BAA6B,CAAC;aAClE,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACjE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YAE9E,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;YAE1E,MAAM,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC/D,IAAI,EAAE,yBAAyB;gBAC/B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,oCAAoC,CAAC;aACzE,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;YACrE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY;YAElE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;YAE1E,MAAM,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC/D,IAAI,EAAE,sBAAsB;gBAC5B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,kCAAkC,CAAC;aACvE,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;YAC5E,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc;YAE7E,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;YAE1E,MAAM,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC/D,IAAI,EAAE,sBAAsB;gBAC5B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,wBAAwB,CAAC;aAC7D,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAC9D,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,gBAAgB,EAAE,CAAC,CAAC,SAAS;iBACnD,qBAAqB,CAAC,gBAAgB,EAAE,CAAC,CAAC,SAAS;iBACnD,qBAAqB,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,SAAS;YAEzD,MAAM,QAAQ,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,cAAc,EAAE,GAAG,EAAE,CAAC,CAAC;YAE/E,MAAM,QAAQ,GAAG;gBACb,EAAE,OAAO,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE;gBACzD,EAAE,OAAO,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE;gBACzD,EAAE,OAAO,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE;aAC/D,CAAC;YAEF,MAAM,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAEpC,gEAAgE;YAChE,MAAM,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YAC1C,MAAM,CAAC,QAAQ,CAAC,CAAC,uBAAuB,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;YACvE,MAAM,CAAC,QAAQ,CAAC,CAAC,uBAAuB,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;YAEvE,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACpD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,OAAO;YAEvD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,eAAe,GAAG;gBACpB,YAAY,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC1C,UAAU,EAAE,EAAE;aACV,CAAC;YAET,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;YAElE,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;YAC5C,MAAM,CAAC,KAAK,CAAC,CAAC,wBAAwB,CAClC,uFAAuF,EACvF,MAAM,CAAC,gBAAgB,CAAC;gBACpB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;gBAC3D,MAAM,EAAE,MAAM;aACjB,CAAC,CACL,CAAC;QACN,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YACvD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAE7D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YAEjD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YAC/C,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,gBAAgB,EAAE,CAAC,CAAC,SAAS;iBACnD,qBAAqB,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,SAAS;YAEzD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,YAAY,GAAG;gBACjB,EAAE,YAAY,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAS;gBAC/D,EAAE,YAAY,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAS;aAClE,CAAC;YAEF,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;YAE5D,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;YAChD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YACxD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YAEvG,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,eAAe,GAAG,EAAE,YAAY,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAS,CAAC;YAE9F,MAAM,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC3E,IAAI,EAAE,yBAAyB;gBAC/B,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,CAAC;aAC1D,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;YACxD,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iBACX,qBAAqB,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS;iBACrD,qBAAqB,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;YAEzD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnD,MAAM,eAAe,GAAG,EAAE,YAAY,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAS,CAAC;YAE9F,MAAM,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;gBAC3E,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,6BAA6B,CAAC;aAClE,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SolanaSigner } from '@solana/keychain-core';
|
|
2
|
+
import { SignerTestConfig, TestScenario } from '@solana/keychain-test-utils';
|
|
3
|
+
export declare function getConfig(scenarios: TestScenario[]): Promise<SignerTestConfig<SolanaSigner>>;
|
|
4
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAiB7E,wBAAsB,SAAS,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAKlG"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createParaSigner } from '../para-signer';
|
|
2
|
+
const SIGNER_TYPE = 'para';
|
|
3
|
+
const REQUIRED_ENV_VARS = ['PARA_API_KEY', 'PARA_WALLET_ID'];
|
|
4
|
+
const CONFIG = {
|
|
5
|
+
signerType: SIGNER_TYPE,
|
|
6
|
+
requiredEnvVars: REQUIRED_ENV_VARS,
|
|
7
|
+
createSigner: () => createParaSigner({
|
|
8
|
+
apiKey: process.env.PARA_API_KEY,
|
|
9
|
+
apiBaseUrl: process.env.PARA_API_BASE_URL,
|
|
10
|
+
walletId: process.env.PARA_WALLET_ID,
|
|
11
|
+
}),
|
|
12
|
+
};
|
|
13
|
+
export async function getConfig(scenarios) {
|
|
14
|
+
return {
|
|
15
|
+
...CONFIG,
|
|
16
|
+
testScenarios: scenarios,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,GAAG,MAAM,CAAC;AAC3B,MAAM,iBAAiB,GAAG,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;AAE7D,MAAM,MAAM,GAAmC;IAC3C,UAAU,EAAE,WAAW;IACvB,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,GAAG,EAAE,CACf,gBAAgB,CAAC;QACb,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,YAAa;QACjC,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;QACzC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,cAAe;KACxC,CAAC;CACT,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,SAAyB;IACrD,OAAO;QACH,GAAG,MAAM;QACT,aAAa,EAAE,SAAS;KAC3B,CAAC;AACN,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ParaSigner, createParaSigner } from './para-signer.js';
|
|
2
|
+
export type { ParaSignerConfig } from './para-signer.js';
|
|
3
|
+
export type { ParaErrorResponse, ParaSignRawRequest, ParaSignRawResponse, ParaWalletResponse } from './types.js';
|
|
4
|
+
export { assertIsSolanaSigner, isSolanaSigner } from '@solana/keychain-core';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAChE,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACjH,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGhE,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
|