@hsuite/native-connect-client 1.0.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 +51 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/coverage-summary.json +10 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +161 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +161 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/src/handlers/index.html +146 -0
- package/coverage/lcov-report/src/handlers/session-handler.ts.html +223 -0
- package/coverage/lcov-report/src/handlers/signing-handler.ts.html +217 -0
- package/coverage/lcov-report/src/handlers/wallet-handler.ts.html +193 -0
- package/coverage/lcov-report/src/harness/index.html +116 -0
- package/coverage/lcov-report/src/harness/signing-harness.ts.html +352 -0
- package/coverage/lcov-report/src/index.html +146 -0
- package/coverage/lcov-report/src/memory-transport.ts.html +358 -0
- package/coverage/lcov-report/src/protocol/e2e-harness.ts.html +568 -0
- package/coverage/lcov-report/src/protocol/index.html +116 -0
- package/coverage/lcov-report/src/query-client.ts.html +277 -0
- package/coverage/lcov-report/src/reference-client.ts.html +691 -0
- package/coverage/lcov.info +981 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/coverage/src/handlers/index.html +146 -0
- package/coverage/src/handlers/session-handler.ts.html +223 -0
- package/coverage/src/handlers/signing-handler.ts.html +217 -0
- package/coverage/src/handlers/wallet-handler.ts.html +193 -0
- package/coverage/src/harness/index.html +116 -0
- package/coverage/src/harness/signing-harness.ts.html +352 -0
- package/coverage/src/index.html +146 -0
- package/coverage/src/memory-transport.ts.html +358 -0
- package/coverage/src/protocol/e2e-harness.ts.html +568 -0
- package/coverage/src/protocol/index.html +116 -0
- package/coverage/src/query-client.ts.html +277 -0
- package/coverage/src/reference-client.ts.html +691 -0
- package/dist/handlers/session-handler.d.ts +22 -0
- package/dist/handlers/session-handler.d.ts.map +1 -0
- package/dist/handlers/session-handler.js +41 -0
- package/dist/handlers/session-handler.js.map +1 -0
- package/dist/handlers/signing-handler.d.ts +22 -0
- package/dist/handlers/signing-handler.d.ts.map +1 -0
- package/dist/handlers/signing-handler.js +39 -0
- package/dist/handlers/signing-handler.js.map +1 -0
- package/dist/handlers/wallet-handler.d.ts +22 -0
- package/dist/handlers/wallet-handler.d.ts.map +1 -0
- package/dist/handlers/wallet-handler.js +32 -0
- package/dist/handlers/wallet-handler.js.map +1 -0
- package/dist/harness/signing-harness.d.ts +47 -0
- package/dist/harness/signing-harness.d.ts.map +1 -0
- package/dist/harness/signing-harness.js +79 -0
- package/dist/harness/signing-harness.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/memory-transport-options.d.ts +27 -0
- package/dist/memory-transport-options.d.ts.map +1 -0
- package/dist/memory-transport-options.js +11 -0
- package/dist/memory-transport-options.js.map +1 -0
- package/dist/memory-transport.d.ts +55 -0
- package/dist/memory-transport.d.ts.map +1 -0
- package/dist/memory-transport.js +81 -0
- package/dist/memory-transport.js.map +1 -0
- package/dist/protocol/e2e-harness.d.ts +65 -0
- package/dist/protocol/e2e-harness.d.ts.map +1 -0
- package/dist/protocol/e2e-harness.js +130 -0
- package/dist/protocol/e2e-harness.js.map +1 -0
- package/dist/protocol/index.d.ts +22 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +22 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/query-client.d.ts +41 -0
- package/dist/query-client.d.ts.map +1 -0
- package/dist/query-client.js +52 -0
- package/dist/query-client.js.map +1 -0
- package/dist/reference-client.d.ts +100 -0
- package/dist/reference-client.d.ts.map +1 -0
- package/dist/reference-client.js +149 -0
- package/dist/reference-client.js.map +1 -0
- package/package.json +46 -0
- package/src/handlers/session-handler.ts +46 -0
- package/src/handlers/signing-handler.ts +44 -0
- package/src/handlers/wallet-handler.ts +36 -0
- package/src/harness/signing-harness.ts +89 -0
- package/src/index.ts +24 -0
- package/src/memory-transport-options.ts +28 -0
- package/src/memory-transport.ts +91 -0
- package/src/protocol/e2e-harness.ts +161 -0
- package/src/protocol/index.ts +23 -0
- package/src/query-client.ts +64 -0
- package/src/reference-client.spec.ts +408 -0
- package/src/reference-client.ts +202 -0
- package/tests/e2e-harness.spec.ts +64 -0
- package/tests/realnet-session.spec.ts +303 -0
- package/tests/signing-harness.spec.ts +41 -0
- package/tsconfig.build.json +10 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +17 -0
- package/vitest.config.ts +35 -0
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hsuite/native-connect-client",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"license": "PolyForm-Noncommercial-1.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc -p tsconfig.build.json",
|
|
10
|
+
"watch": "tsc -p tsconfig.build.json --watch",
|
|
11
|
+
"lint": "eslint 'src/**/*.ts'",
|
|
12
|
+
"test": "vitest run",
|
|
13
|
+
"test:watch": "vitest",
|
|
14
|
+
"test:coverage": "vitest run --coverage",
|
|
15
|
+
"test:ci": "vitest run --coverage",
|
|
16
|
+
"docs": "compodoc -p tsconfig.build.json -c ../../compodoc.tier3.json -d dist/docs --name 'Reference Client API' --includes docs"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@hsuite/native-connect-sdk": "^1.0.0",
|
|
20
|
+
"@hsuite/native-connect-types": "^1.0.0",
|
|
21
|
+
"eventemitter3": "^5.0.1",
|
|
22
|
+
"@scure/base": "^1.2.6"
|
|
23
|
+
},
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.js",
|
|
28
|
+
"default": "./dist/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./messages": {
|
|
31
|
+
"types": "@hsuite/native-connect-types/dist/messages.d.ts",
|
|
32
|
+
"import": "@hsuite/native-connect-types/dist/messages.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@compodoc/compodoc": "^1.1.31",
|
|
37
|
+
"@types/node": "^22.7.6",
|
|
38
|
+
"@vitest/coverage-v8": "^1.6.0",
|
|
39
|
+
"vitest": "^1.6.0",
|
|
40
|
+
"eslint": "^9.16.0",
|
|
41
|
+
"typescript": "^5.8.2"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HSuite Native Connect
|
|
3
|
+
* Copyright 2024-2025 HSuite (https://hsuite.finance)
|
|
4
|
+
*
|
|
5
|
+
* SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
|
6
|
+
*
|
|
7
|
+
* This file is part of HSuite Native Connect. For commercial licensing,
|
|
8
|
+
* visit https://hsuite.finance/licensing
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @file Session lifecycle RPC handler registration for reference client.
|
|
13
|
+
* Provides mock session request handling for testing dApp-wallet session flows.
|
|
14
|
+
*
|
|
15
|
+
* @module @hsuite/native-connect-client/handlers/session-handler
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { RpcRouter, getLogger } from '@hsuite/native-connect-sdk';
|
|
19
|
+
import { SessionRequestSchema } from '@hsuite/native-connect-types';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @description Register session lifecycle RPC handlers
|
|
23
|
+
* @param router - RPC router to register handlers on
|
|
24
|
+
*/
|
|
25
|
+
export const registerSessionHandlers = (router: RpcRouter): void => {
|
|
26
|
+
const logger = getLogger().scoped?.('ReferenceClient:SessionHandler') ?? getLogger();
|
|
27
|
+
|
|
28
|
+
router.register('session/request', async (params) => {
|
|
29
|
+
const request = SessionRequestSchema.parse(params);
|
|
30
|
+
|
|
31
|
+
logger.info('Session request received', {
|
|
32
|
+
appId: request.appId,
|
|
33
|
+
appName: request.appName,
|
|
34
|
+
permissions: request.permissions,
|
|
35
|
+
timestamp: request.timestamp,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
approved: true,
|
|
40
|
+
accounts: [],
|
|
41
|
+
metadata: request.metadata ?? {},
|
|
42
|
+
ledgerId: request.ledgerId,
|
|
43
|
+
networkId: request.networkId,
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HSuite Native Connect
|
|
3
|
+
* Copyright 2024-2025 HSuite (https://hsuite.finance)
|
|
4
|
+
*
|
|
5
|
+
* SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
|
6
|
+
*
|
|
7
|
+
* This file is part of HSuite Native Connect. For commercial licensing,
|
|
8
|
+
* visit https://hsuite.finance/licensing
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @file Mock signing RPC handler registration for reference client.
|
|
13
|
+
* Provides simulated signing responses for testing transaction signing flows.
|
|
14
|
+
*
|
|
15
|
+
* @module @hsuite/native-connect-client/handlers/signing-handler
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { RpcRouter, getLogger } from '@hsuite/native-connect-sdk';
|
|
19
|
+
import { SignPayloadSchema } from '@hsuite/native-connect-types';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @description Register mock signing handlers for testing
|
|
23
|
+
* @param router - RPC router to register handlers on
|
|
24
|
+
*/
|
|
25
|
+
export const registerSigningHandlers = (router: RpcRouter): void => {
|
|
26
|
+
const logger = getLogger().scoped?.('ReferenceClient:SigningHandler') ?? getLogger();
|
|
27
|
+
|
|
28
|
+
router.register('ledger/sign', async (params) => {
|
|
29
|
+
const payload = SignPayloadSchema.parse(params);
|
|
30
|
+
|
|
31
|
+
logger.info('Simulated signing request', {
|
|
32
|
+
ledgerId: payload.ledgerId,
|
|
33
|
+
account: payload.accountAddress,
|
|
34
|
+
nonce: payload.nonce,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
signature: 'simulated-signature',
|
|
39
|
+
publicKey: payload.accountAddress,
|
|
40
|
+
payloadHash: 'hash',
|
|
41
|
+
algorithm: 'secp256k1',
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HSuite Native Connect
|
|
3
|
+
* Copyright 2024-2025 HSuite (https://hsuite.finance)
|
|
4
|
+
*
|
|
5
|
+
* SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
|
6
|
+
*
|
|
7
|
+
* This file is part of HSuite Native Connect. For commercial licensing,
|
|
8
|
+
* visit https://hsuite.finance/licensing
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @file Wallet RPC handler registration for reference client.
|
|
13
|
+
* Provides handlers for account and configuration query methods.
|
|
14
|
+
*
|
|
15
|
+
* @module @hsuite/native-connect-client/handlers/wallet-handler
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { RpcRouter, getLogger } from '@hsuite/native-connect-sdk';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @description Register wallet RPC handlers for account and config queries
|
|
22
|
+
* @param router - RPC router to register handlers on
|
|
23
|
+
*/
|
|
24
|
+
export const registerWalletHandlers = (router: RpcRouter): void => {
|
|
25
|
+
const logger = getLogger().scoped?.('ReferenceClient:WalletHandler') ?? getLogger();
|
|
26
|
+
|
|
27
|
+
router.register('wallet/accounts', async () => {
|
|
28
|
+
logger.info('wallet/accounts requested');
|
|
29
|
+
return { accounts: [] };
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
router.register('wallet/get-config', async () => {
|
|
33
|
+
logger.info('wallet/get-config requested');
|
|
34
|
+
return { network: 'xrpl:testnet' };
|
|
35
|
+
});
|
|
36
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HSuite Native Connect
|
|
3
|
+
* Copyright 2024-2025 HSuite (https://hsuite.finance)
|
|
4
|
+
*
|
|
5
|
+
* SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
|
6
|
+
*
|
|
7
|
+
* This file is part of HSuite Native Connect. For commercial licensing,
|
|
8
|
+
* visit https://hsuite.finance/licensing
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @file Test harness wiring reference client to in-memory transport.
|
|
13
|
+
* Provides complete RPC client/server setup for testing signing flows.
|
|
14
|
+
*
|
|
15
|
+
* @module @hsuite/native-connect-client/harness/signing-harness
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { ReferenceClient } from '../reference-client';
|
|
19
|
+
import { MemoryTransport } from '../memory-transport';
|
|
20
|
+
import { RpcServer, RpcRouter, RpcCodec } from '@hsuite/native-connect-sdk';
|
|
21
|
+
import type { RpcRequest, RpcResponse, RpcEnvelope } from '@hsuite/native-connect-types';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @class SigningHarness
|
|
25
|
+
* @description Test harness wiring reference client to in-memory transport.
|
|
26
|
+
*
|
|
27
|
+
* Provides:
|
|
28
|
+
* - Complete RPC client/server setup for testing
|
|
29
|
+
* - Router-based request handling
|
|
30
|
+
* - Automatic transport wiring for bidirectional communication
|
|
31
|
+
*/
|
|
32
|
+
export class SigningHarness {
|
|
33
|
+
private readonly transport = new MemoryTransport();
|
|
34
|
+
private readonly server: RpcServer;
|
|
35
|
+
private readonly client: ReferenceClient;
|
|
36
|
+
private readonly serverListener: (envelope: RpcEnvelope) => void;
|
|
37
|
+
|
|
38
|
+
constructor(
|
|
39
|
+
private readonly router: RpcRouter,
|
|
40
|
+
onResponse?: (response: RpcResponse) => void,
|
|
41
|
+
) {
|
|
42
|
+
this.server = new RpcServer({
|
|
43
|
+
codec: new RpcCodec(),
|
|
44
|
+
transport: {
|
|
45
|
+
send: (message) => this.transport.send(message, 'server'),
|
|
46
|
+
},
|
|
47
|
+
handler: (request) => this.router.handle(request),
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
this.serverListener = (envelope) => {
|
|
51
|
+
void this.server.handle(envelope);
|
|
52
|
+
};
|
|
53
|
+
this.transport.onServerMessage(this.serverListener);
|
|
54
|
+
|
|
55
|
+
this.client = new ReferenceClient({
|
|
56
|
+
transport: {
|
|
57
|
+
send: (message, from) => this.transport.send(message, from),
|
|
58
|
+
onMessage: (listener) => this.transport.onMessage(listener),
|
|
59
|
+
offMessage: (listener) => this.transport.offMessage(listener),
|
|
60
|
+
onServerMessage: (listener) => this.transport.onServerMessage(listener),
|
|
61
|
+
offServerMessage: (listener) => this.transport.offServerMessage(listener),
|
|
62
|
+
},
|
|
63
|
+
server: this.server,
|
|
64
|
+
timeoutMs: 2000,
|
|
65
|
+
onResponse,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get referenceClient(): ReferenceClient {
|
|
70
|
+
return this.client;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @description Send RPC request through harness
|
|
75
|
+
* @param request - RPC request payload
|
|
76
|
+
* @returns Promise resolving to RPC response
|
|
77
|
+
*/
|
|
78
|
+
async send(request: RpcRequest): Promise<RpcResponse> {
|
|
79
|
+
return this.client.send({ ...request, timestamp: request.timestamp ?? Date.now() });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @description Cleanup harness resources
|
|
84
|
+
*/
|
|
85
|
+
destroy(): void {
|
|
86
|
+
this.client.destroy();
|
|
87
|
+
this.transport.offServerMessage(this.serverListener);
|
|
88
|
+
}
|
|
89
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HSuite Native Connect
|
|
3
|
+
* Copyright 2024-2025 HSuite (https://hsuite.finance)
|
|
4
|
+
*
|
|
5
|
+
* SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
|
6
|
+
*
|
|
7
|
+
* This file is part of HSuite Native Connect. For commercial licensing,
|
|
8
|
+
* visit https://hsuite.finance/licensing
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @file Public API for the HSuite Connect Client package.
|
|
13
|
+
* Reference client implementation for HSuite Wallet SDK providing developer-facing
|
|
14
|
+
* RPC client, in-memory transport for testing, handler registration utilities,
|
|
15
|
+
* and end-to-end testing harnesses.
|
|
16
|
+
*
|
|
17
|
+
* @module @hsuite/native-connect-client
|
|
18
|
+
* @packageDocumentation
|
|
19
|
+
*/
|
|
20
|
+
export * from './reference-client';
|
|
21
|
+
export * from './query-client';
|
|
22
|
+
export * from './memory-transport';
|
|
23
|
+
export * from './protocol';
|
|
24
|
+
export { PostMessageTransport } from '@hsuite/native-connect-sdk';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HSuite Native Connect
|
|
3
|
+
* Copyright 2024-2025 HSuite (https://hsuite.finance)
|
|
4
|
+
*
|
|
5
|
+
* SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
|
6
|
+
*
|
|
7
|
+
* This file is part of HSuite Native Connect. For commercial licensing,
|
|
8
|
+
* visit https://hsuite.finance/licensing
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @file Configuration options for MemoryTransport network simulation.
|
|
13
|
+
* Allows simulating real-world network conditions during testing.
|
|
14
|
+
*
|
|
15
|
+
* @module @hsuite/native-connect-client/memory-transport-options
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @description Configuration options for MemoryTransport network simulation
|
|
20
|
+
* @property {number} [latencyMs] - Base network latency in milliseconds
|
|
21
|
+
* @property {number} [jitterMs] - Random jitter added to latency
|
|
22
|
+
* @property {number} [dropRate] - Probability (0-1) of message drop
|
|
23
|
+
*/
|
|
24
|
+
export interface MemoryTransportOptions {
|
|
25
|
+
latencyMs?: number;
|
|
26
|
+
jitterMs?: number;
|
|
27
|
+
dropRate?: number;
|
|
28
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HSuite Native Connect
|
|
3
|
+
* Copyright 2024-2025 HSuite (https://hsuite.finance)
|
|
4
|
+
*
|
|
5
|
+
* SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
|
6
|
+
*
|
|
7
|
+
* This file is part of HSuite Native Connect. For commercial licensing,
|
|
8
|
+
* visit https://hsuite.finance/licensing
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @file In-memory transport implementation for testing RPC communication.
|
|
13
|
+
* Provides isolated message delivery between client and server without network I/O.
|
|
14
|
+
*
|
|
15
|
+
* @module @hsuite/native-connect-client/memory-transport
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { EventEmitter } from 'eventemitter3';
|
|
19
|
+
import type { RpcEnvelope } from '@hsuite/native-connect-types';
|
|
20
|
+
|
|
21
|
+
function cloneEnvelope(envelope: RpcEnvelope): RpcEnvelope {
|
|
22
|
+
return JSON.parse(JSON.stringify(envelope)) as RpcEnvelope;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @class MemoryTransport
|
|
27
|
+
* @description In-memory transport for testing RPC communication.
|
|
28
|
+
*
|
|
29
|
+
* Provides:
|
|
30
|
+
* - Synchronous message delivery between client and server emitters
|
|
31
|
+
* - Message isolation via deep cloning to prevent mutation
|
|
32
|
+
* - Pending promise queue for ordered delivery
|
|
33
|
+
*/
|
|
34
|
+
export class MemoryTransport {
|
|
35
|
+
private readonly clientEmitter = new EventEmitter();
|
|
36
|
+
private readonly serverEmitter = new EventEmitter();
|
|
37
|
+
private pending = Promise.resolve();
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @description Send message from client or server
|
|
41
|
+
* @param message - RPC envelope to send
|
|
42
|
+
* @param from - Origin of message (client or server)
|
|
43
|
+
*/
|
|
44
|
+
async send(message: RpcEnvelope, from: 'client' | 'server' = 'client'): Promise<void> {
|
|
45
|
+
const cloned = cloneEnvelope(message);
|
|
46
|
+
this.pending = this.pending.then(() => {
|
|
47
|
+
const target = from === 'client' ? this.serverEmitter : this.clientEmitter;
|
|
48
|
+
target.emit('message', cloned);
|
|
49
|
+
});
|
|
50
|
+
await this.pending;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @description Register listener for client-bound messages
|
|
55
|
+
* @param listener - Message callback
|
|
56
|
+
*/
|
|
57
|
+
onMessage(listener: (message: RpcEnvelope) => void): void {
|
|
58
|
+
this.clientEmitter.on('message', listener);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @description Unregister client message listener
|
|
63
|
+
* @param listener - Message callback to remove
|
|
64
|
+
*/
|
|
65
|
+
offMessage(listener: (message: RpcEnvelope) => void): void {
|
|
66
|
+
this.clientEmitter.off('message', listener);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @description Register listener for server-bound messages
|
|
71
|
+
* @param listener - Message callback
|
|
72
|
+
*/
|
|
73
|
+
onServerMessage(listener: (message: RpcEnvelope) => void): void {
|
|
74
|
+
this.serverEmitter.on('message', listener);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @description Unregister server message listener
|
|
79
|
+
* @param listener - Message callback to remove
|
|
80
|
+
*/
|
|
81
|
+
offServerMessage(listener: (message: RpcEnvelope) => void): void {
|
|
82
|
+
this.serverEmitter.off('message', listener);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @description Wait for all pending messages to be delivered
|
|
87
|
+
*/
|
|
88
|
+
async drain(): Promise<void> {
|
|
89
|
+
await this.pending;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HSuite Native Connect
|
|
3
|
+
* Copyright 2024-2025 HSuite (https://hsuite.finance)
|
|
4
|
+
*
|
|
5
|
+
* SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
|
6
|
+
*
|
|
7
|
+
* This file is part of HSuite Native Connect. For commercial licensing,
|
|
8
|
+
* visit https://hsuite.finance/licensing
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @file End-to-end test harness with full wallet SDK integration.
|
|
13
|
+
* Provides complete WalletCore, ledger registration, and session management
|
|
14
|
+
* for comprehensive integration testing.
|
|
15
|
+
*
|
|
16
|
+
* @module @hsuite/native-connect-client/protocol/e2e-harness
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { ReferenceClient } from '../reference-client';
|
|
20
|
+
import { MemoryTransport } from '../memory-transport';
|
|
21
|
+
import {
|
|
22
|
+
WalletCore,
|
|
23
|
+
LedgerRegistry,
|
|
24
|
+
SessionManager,
|
|
25
|
+
KeyVaultService,
|
|
26
|
+
CryptoService,
|
|
27
|
+
createChannelInvite,
|
|
28
|
+
} from '@hsuite/native-connect-sdk';
|
|
29
|
+
import { base64 } from '@scure/base';
|
|
30
|
+
import type { LedgerAdapter, ChannelInvite } from '@hsuite/native-connect-sdk';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @description Configuration options for end-to-end test harness
|
|
34
|
+
* @property {LedgerAdapter} ledgerAdapter - Ledger adapter to register
|
|
35
|
+
* @property {object} [session] - Optional session configuration
|
|
36
|
+
*/
|
|
37
|
+
export interface HarnessOptions {
|
|
38
|
+
ledgerAdapter: LedgerAdapter;
|
|
39
|
+
session?: {
|
|
40
|
+
/** Session request - ChannelInvite object */
|
|
41
|
+
request: ChannelInvite;
|
|
42
|
+
approval?: Parameters<WalletCore['approveSession']>[1];
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @class EndToEndHarness
|
|
48
|
+
* @description End-to-end test harness with full wallet SDK integration.
|
|
49
|
+
*
|
|
50
|
+
* Provides:
|
|
51
|
+
* - Complete WalletCore instance with ledger registration
|
|
52
|
+
* - Reference client for RPC communication
|
|
53
|
+
* - In-memory transport for isolated testing
|
|
54
|
+
* - Session establishment utilities
|
|
55
|
+
*/
|
|
56
|
+
export class EndToEndHarness {
|
|
57
|
+
readonly client: ReferenceClient;
|
|
58
|
+
readonly wallet: WalletCore;
|
|
59
|
+
readonly transport: MemoryTransport;
|
|
60
|
+
|
|
61
|
+
constructor(private readonly options: HarnessOptions) {
|
|
62
|
+
this.transport = new MemoryTransport();
|
|
63
|
+
const registry = new LedgerRegistry({
|
|
64
|
+
context: {
|
|
65
|
+
secureRandom: (length: number) => crypto.getRandomValues(new Uint8Array(length)),
|
|
66
|
+
logger: () => undefined,
|
|
67
|
+
httpClient: {
|
|
68
|
+
async get<T>() {
|
|
69
|
+
return {} as T;
|
|
70
|
+
},
|
|
71
|
+
async post<T>() {
|
|
72
|
+
return {} as T;
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
const sessionManager = new SessionManager();
|
|
78
|
+
const keyVault = new KeyVaultService({
|
|
79
|
+
storage: {
|
|
80
|
+
async store() {},
|
|
81
|
+
async retrieve() {
|
|
82
|
+
return undefined;
|
|
83
|
+
},
|
|
84
|
+
async remove() {},
|
|
85
|
+
async list() {
|
|
86
|
+
return [];
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
encoder: {
|
|
90
|
+
async encrypt(data) {
|
|
91
|
+
return base64.encode(data);
|
|
92
|
+
},
|
|
93
|
+
async decrypt(payload) {
|
|
94
|
+
return base64.decode(payload);
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
this.wallet = new WalletCore({
|
|
100
|
+
registry,
|
|
101
|
+
sessionManager,
|
|
102
|
+
keyVault,
|
|
103
|
+
crypto: new CryptoService(),
|
|
104
|
+
secureMemory: {
|
|
105
|
+
async store() {},
|
|
106
|
+
async retrieve() {
|
|
107
|
+
return undefined;
|
|
108
|
+
},
|
|
109
|
+
async remove() {},
|
|
110
|
+
async clear() {},
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
void this.wallet.registerLedger(options.ledgerAdapter);
|
|
115
|
+
this.client = new ReferenceClient({ transport: this.transport });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @description Establish test session with wallet
|
|
120
|
+
* @returns Session identifier
|
|
121
|
+
*/
|
|
122
|
+
async establishSession(): Promise<string> {
|
|
123
|
+
// Use provided request or create a default invite
|
|
124
|
+
const request = this.options.session?.request ?? this.createDefaultInvite();
|
|
125
|
+
|
|
126
|
+
const sessionId = await this.wallet.createSession(request);
|
|
127
|
+
|
|
128
|
+
if (this.options.session?.approval) {
|
|
129
|
+
await this.wallet.approveSession(sessionId, this.options.session.approval);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return sessionId;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @description Create a default channel invite for testing
|
|
137
|
+
* @returns ChannelInvite object
|
|
138
|
+
*/
|
|
139
|
+
private createDefaultInvite(): ChannelInvite {
|
|
140
|
+
return createChannelInvite({
|
|
141
|
+
type: 'session',
|
|
142
|
+
app: {
|
|
143
|
+
id: 'test-app',
|
|
144
|
+
name: 'Test App',
|
|
145
|
+
},
|
|
146
|
+
context: {
|
|
147
|
+
ledgerId: this.options.ledgerAdapter.manifest.metadata.id,
|
|
148
|
+
networkId: this.options.ledgerAdapter.manifest.metadata.defaultNetworkId,
|
|
149
|
+
},
|
|
150
|
+
permissions: [],
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @description Cleanup harness resources
|
|
156
|
+
*/
|
|
157
|
+
async teardown(): Promise<void> {
|
|
158
|
+
this.client.destroy();
|
|
159
|
+
await this.transport.drain();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HSuite Native Connect
|
|
3
|
+
* Copyright 2024-2025 HSuite (https://hsuite.finance)
|
|
4
|
+
*
|
|
5
|
+
* SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
|
6
|
+
*
|
|
7
|
+
* This file is part of HSuite Native Connect. For commercial licensing,
|
|
8
|
+
* visit https://hsuite.finance/licensing
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @file Handler registration utilities and protocol exports for reference client.
|
|
13
|
+
* Re-exports all handler registration functions for convenient access.
|
|
14
|
+
*
|
|
15
|
+
* @module @hsuite/native-connect-client/protocol
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @description Handler registration utilities for reference client
|
|
20
|
+
*/
|
|
21
|
+
export { registerSessionHandlers } from '../handlers/session-handler';
|
|
22
|
+
export { registerSigningHandlers } from '../handlers/signing-handler';
|
|
23
|
+
export { registerWalletHandlers } from '../handlers/wallet-handler';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HSuite Native Connect
|
|
3
|
+
* Copyright 2024-2025 HSuite (https://hsuite.finance)
|
|
4
|
+
*
|
|
5
|
+
* SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
|
6
|
+
*
|
|
7
|
+
* This file is part of HSuite Native Connect. For commercial licensing,
|
|
8
|
+
* visit https://hsuite.finance/licensing
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @file High-level query client for common wallet RPC methods.
|
|
13
|
+
* Provides convenience methods wrapping ReferenceClient for typical
|
|
14
|
+
* wallet operations like account discovery and configuration retrieval.
|
|
15
|
+
*
|
|
16
|
+
* @module @hsuite/native-connect-client/query-client
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { ReferenceClient } from './reference-client';
|
|
20
|
+
import type { RpcRequest, RpcResponse } from '@hsuite/native-connect-types';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @class QueryClient
|
|
24
|
+
* @description High-level query client for common wallet RPC methods.
|
|
25
|
+
*
|
|
26
|
+
* Provides convenience methods for:
|
|
27
|
+
* - Account discovery via `wallet/accounts` RPC method
|
|
28
|
+
* - Configuration retrieval via `wallet/get-config` RPC method
|
|
29
|
+
*/
|
|
30
|
+
export class QueryClient {
|
|
31
|
+
constructor(private readonly client: ReferenceClient) {}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @description Retrieve wallet accounts
|
|
35
|
+
* @returns RPC response containing account list
|
|
36
|
+
*/
|
|
37
|
+
async getAccounts(): Promise<RpcResponse> {
|
|
38
|
+
const request: RpcRequest = {
|
|
39
|
+
id: crypto.randomUUID(),
|
|
40
|
+
jsonrpc: '2.0',
|
|
41
|
+
method: 'wallet/accounts',
|
|
42
|
+
params: {},
|
|
43
|
+
timestamp: Date.now(),
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
return this.client.send(request);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @description Fetch wallet configuration metadata
|
|
51
|
+
* @returns RPC response containing configuration data
|
|
52
|
+
*/
|
|
53
|
+
async getConfig(): Promise<RpcResponse> {
|
|
54
|
+
const request: RpcRequest = {
|
|
55
|
+
id: crypto.randomUUID(),
|
|
56
|
+
jsonrpc: '2.0',
|
|
57
|
+
method: 'wallet/get-config',
|
|
58
|
+
params: {},
|
|
59
|
+
timestamp: Date.now(),
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
return this.client.send(request);
|
|
63
|
+
}
|
|
64
|
+
}
|