@waiaas/daemon 2.11.0-rc → 2.11.0-rc.13
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/dist/api/middleware/resolve-asset.d.ts +26 -0
- package/dist/api/middleware/resolve-asset.d.ts.map +1 -0
- package/dist/api/middleware/resolve-asset.js +81 -0
- package/dist/api/middleware/resolve-asset.js.map +1 -0
- package/dist/api/routes/actions.d.ts +4 -0
- package/dist/api/routes/actions.d.ts.map +1 -1
- package/dist/api/routes/actions.js +120 -0
- package/dist/api/routes/actions.js.map +1 -1
- package/dist/api/routes/admin-auth.d.ts.map +1 -1
- package/dist/api/routes/admin-auth.js +4 -1
- package/dist/api/routes/admin-auth.js.map +1 -1
- package/dist/api/routes/admin-credentials.d.ts +20 -0
- package/dist/api/routes/admin-credentials.d.ts.map +1 -0
- package/dist/api/routes/admin-credentials.js +115 -0
- package/dist/api/routes/admin-credentials.js.map +1 -0
- package/dist/api/routes/admin-settings.d.ts.map +1 -1
- package/dist/api/routes/admin-settings.js +70 -1
- package/dist/api/routes/admin-settings.js.map +1 -1
- package/dist/api/routes/admin-wallets.d.ts.map +1 -1
- package/dist/api/routes/admin-wallets.js +27 -14
- package/dist/api/routes/admin-wallets.js.map +1 -1
- package/dist/api/routes/connect-info.d.ts +2 -0
- package/dist/api/routes/connect-info.d.ts.map +1 -1
- package/dist/api/routes/connect-info.js +32 -1
- package/dist/api/routes/connect-info.js.map +1 -1
- package/dist/api/routes/credentials.d.ts +20 -0
- package/dist/api/routes/credentials.d.ts.map +1 -0
- package/dist/api/routes/credentials.js +120 -0
- package/dist/api/routes/credentials.js.map +1 -0
- package/dist/api/routes/defi-positions.d.ts.map +1 -1
- package/dist/api/routes/defi-positions.js +10 -0
- package/dist/api/routes/defi-positions.js.map +1 -1
- package/dist/api/routes/external-actions.d.ts +19 -0
- package/dist/api/routes/external-actions.d.ts.map +1 -0
- package/dist/api/routes/external-actions.js +199 -0
- package/dist/api/routes/external-actions.js.map +1 -0
- package/dist/api/routes/incoming.d.ts.map +1 -1
- package/dist/api/routes/incoming.js +2 -1
- package/dist/api/routes/incoming.js.map +1 -1
- package/dist/api/routes/index.d.ts +3 -0
- package/dist/api/routes/index.d.ts.map +1 -1
- package/dist/api/routes/index.js +3 -0
- package/dist/api/routes/index.js.map +1 -1
- package/dist/api/routes/nfts.js +24 -4
- package/dist/api/routes/nfts.js.map +1 -1
- package/dist/api/routes/openapi-schemas.d.ts +321 -139
- package/dist/api/routes/openapi-schemas.d.ts.map +1 -1
- package/dist/api/routes/openapi-schemas.js +24 -0
- package/dist/api/routes/openapi-schemas.js.map +1 -1
- package/dist/api/routes/rpc-proxy.d.ts +55 -0
- package/dist/api/routes/rpc-proxy.d.ts.map +1 -0
- package/dist/api/routes/rpc-proxy.js +285 -0
- package/dist/api/routes/rpc-proxy.js.map +1 -0
- package/dist/api/routes/staking.d.ts.map +1 -1
- package/dist/api/routes/staking.js +15 -0
- package/dist/api/routes/staking.js.map +1 -1
- package/dist/api/routes/tokens.d.ts.map +1 -1
- package/dist/api/routes/tokens.js +8 -1
- package/dist/api/routes/tokens.js.map +1 -1
- package/dist/api/routes/transactions.d.ts +35 -0
- package/dist/api/routes/transactions.d.ts.map +1 -1
- package/dist/api/routes/transactions.js +220 -20
- package/dist/api/routes/transactions.js.map +1 -1
- package/dist/api/routes/wallet.d.ts.map +1 -1
- package/dist/api/routes/wallet.js +18 -4
- package/dist/api/routes/wallet.js.map +1 -1
- package/dist/api/server.d.ts +2 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +52 -1
- package/dist/api/server.js.map +1 -1
- package/dist/infrastructure/action/action-provider-registry.d.ts.map +1 -1
- package/dist/infrastructure/action/action-provider-registry.js +12 -0
- package/dist/infrastructure/action/action-provider-registry.js.map +1 -1
- package/dist/infrastructure/credential/credential-crypto.d.ts +43 -0
- package/dist/infrastructure/credential/credential-crypto.d.ts.map +1 -0
- package/dist/infrastructure/credential/credential-crypto.js +64 -0
- package/dist/infrastructure/credential/credential-crypto.js.map +1 -0
- package/dist/infrastructure/credential/credential-vault.d.ts +42 -0
- package/dist/infrastructure/credential/credential-vault.d.ts.map +1 -0
- package/dist/infrastructure/credential/credential-vault.js +235 -0
- package/dist/infrastructure/credential/credential-vault.js.map +1 -0
- package/dist/infrastructure/credential/index.d.ts +6 -0
- package/dist/infrastructure/credential/index.d.ts.map +1 -0
- package/dist/infrastructure/credential/index.js +6 -0
- package/dist/infrastructure/credential/index.js.map +1 -0
- package/dist/infrastructure/database/migrate.d.ts +1 -1
- package/dist/infrastructure/database/migrate.d.ts.map +1 -1
- package/dist/infrastructure/database/migrate.js +191 -6
- package/dist/infrastructure/database/migrate.js.map +1 -1
- package/dist/infrastructure/database/schema.d.ts +281 -1
- package/dist/infrastructure/database/schema.d.ts.map +1 -1
- package/dist/infrastructure/database/schema.js +34 -3
- package/dist/infrastructure/database/schema.js.map +1 -1
- package/dist/infrastructure/keystore/re-encrypt.d.ts +9 -0
- package/dist/infrastructure/keystore/re-encrypt.d.ts.map +1 -1
- package/dist/infrastructure/keystore/re-encrypt.js +47 -1
- package/dist/infrastructure/keystore/re-encrypt.js.map +1 -1
- package/dist/infrastructure/settings/index.d.ts +2 -2
- package/dist/infrastructure/settings/index.d.ts.map +1 -1
- package/dist/infrastructure/settings/index.js +1 -1
- package/dist/infrastructure/settings/index.js.map +1 -1
- package/dist/infrastructure/settings/setting-keys.d.ts +16 -2
- package/dist/infrastructure/settings/setting-keys.d.ts.map +1 -1
- package/dist/infrastructure/settings/setting-keys.js +296 -206
- package/dist/infrastructure/settings/setting-keys.js.map +1 -1
- package/dist/lifecycle/daemon.d.ts.map +1 -1
- package/dist/lifecycle/daemon.js +31 -0
- package/dist/lifecycle/daemon.js.map +1 -1
- package/dist/notifications/templates/message-templates.d.ts.map +1 -1
- package/dist/notifications/templates/message-templates.js +5 -6
- package/dist/notifications/templates/message-templates.js.map +1 -1
- package/dist/pipeline/database-policy-engine.d.ts +36 -0
- package/dist/pipeline/database-policy-engine.d.ts.map +1 -1
- package/dist/pipeline/database-policy-engine.js +185 -0
- package/dist/pipeline/database-policy-engine.js.map +1 -1
- package/dist/pipeline/external-action-pipeline.d.ts +64 -0
- package/dist/pipeline/external-action-pipeline.d.ts.map +1 -0
- package/dist/pipeline/external-action-pipeline.js +427 -0
- package/dist/pipeline/external-action-pipeline.js.map +1 -0
- package/dist/pipeline/pipeline.d.ts +4 -0
- package/dist/pipeline/pipeline.d.ts.map +1 -1
- package/dist/pipeline/resolve-effective-amount-usd.d.ts.map +1 -1
- package/dist/pipeline/resolve-effective-amount-usd.js +2 -1
- package/dist/pipeline/resolve-effective-amount-usd.js.map +1 -1
- package/dist/pipeline/stages.d.ts.map +1 -1
- package/dist/pipeline/stages.js +59 -10
- package/dist/pipeline/stages.js.map +1 -1
- package/dist/rpc-proxy/completion-waiter.d.ts +35 -0
- package/dist/rpc-proxy/completion-waiter.d.ts.map +1 -0
- package/dist/rpc-proxy/completion-waiter.js +72 -0
- package/dist/rpc-proxy/completion-waiter.js.map +1 -0
- package/dist/rpc-proxy/dispatcher.d.ts +37 -0
- package/dist/rpc-proxy/dispatcher.d.ts.map +1 -0
- package/dist/rpc-proxy/dispatcher.js +54 -0
- package/dist/rpc-proxy/dispatcher.js.map +1 -0
- package/dist/rpc-proxy/index.d.ts +15 -0
- package/dist/rpc-proxy/index.d.ts.map +1 -0
- package/dist/rpc-proxy/index.js +15 -0
- package/dist/rpc-proxy/index.js.map +1 -0
- package/dist/rpc-proxy/json-rpc.d.ts +78 -0
- package/dist/rpc-proxy/json-rpc.d.ts.map +1 -0
- package/dist/rpc-proxy/json-rpc.js +123 -0
- package/dist/rpc-proxy/json-rpc.js.map +1 -0
- package/dist/rpc-proxy/method-handlers.d.ts +54 -0
- package/dist/rpc-proxy/method-handlers.d.ts.map +1 -0
- package/dist/rpc-proxy/method-handlers.js +171 -0
- package/dist/rpc-proxy/method-handlers.js.map +1 -0
- package/dist/rpc-proxy/nonce-tracker.d.ts +39 -0
- package/dist/rpc-proxy/nonce-tracker.d.ts.map +1 -0
- package/dist/rpc-proxy/nonce-tracker.js +80 -0
- package/dist/rpc-proxy/nonce-tracker.js.map +1 -0
- package/dist/rpc-proxy/passthrough.d.ts +37 -0
- package/dist/rpc-proxy/passthrough.d.ts.map +1 -0
- package/dist/rpc-proxy/passthrough.js +86 -0
- package/dist/rpc-proxy/passthrough.js.map +1 -0
- package/dist/rpc-proxy/sync-pipeline.d.ts +40 -0
- package/dist/rpc-proxy/sync-pipeline.d.ts.map +1 -0
- package/dist/rpc-proxy/sync-pipeline.js +74 -0
- package/dist/rpc-proxy/sync-pipeline.js.map +1 -0
- package/dist/rpc-proxy/tx-adapter.d.ts +79 -0
- package/dist/rpc-proxy/tx-adapter.d.ts.map +1 -0
- package/dist/rpc-proxy/tx-adapter.js +117 -0
- package/dist/rpc-proxy/tx-adapter.js.map +1 -0
- package/dist/services/async-polling-service.d.ts.map +1 -1
- package/dist/services/async-polling-service.js +95 -2
- package/dist/services/async-polling-service.js.map +1 -1
- package/dist/signing/bootstrap.d.ts +12 -0
- package/dist/signing/bootstrap.d.ts.map +1 -0
- package/dist/signing/bootstrap.js +15 -0
- package/dist/signing/bootstrap.js.map +1 -0
- package/dist/signing/capabilities/ecdsa-signer.d.ts +7 -0
- package/dist/signing/capabilities/ecdsa-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/ecdsa-signer.js +42 -0
- package/dist/signing/capabilities/ecdsa-signer.js.map +1 -0
- package/dist/signing/capabilities/ed25519-signer.d.ts +7 -0
- package/dist/signing/capabilities/ed25519-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/ed25519-signer.js +39 -0
- package/dist/signing/capabilities/ed25519-signer.js.map +1 -0
- package/dist/signing/capabilities/eip712-signer.d.ts +7 -0
- package/dist/signing/capabilities/eip712-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/eip712-signer.js +35 -0
- package/dist/signing/capabilities/eip712-signer.js.map +1 -0
- package/dist/signing/capabilities/erc8128-signer.d.ts +7 -0
- package/dist/signing/capabilities/erc8128-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/erc8128-signer.js +55 -0
- package/dist/signing/capabilities/erc8128-signer.js.map +1 -0
- package/dist/signing/capabilities/hmac-signer.d.ts +7 -0
- package/dist/signing/capabilities/hmac-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/hmac-signer.js +32 -0
- package/dist/signing/capabilities/hmac-signer.js.map +1 -0
- package/dist/signing/capabilities/index.d.ts +13 -0
- package/dist/signing/capabilities/index.d.ts.map +1 -0
- package/dist/signing/capabilities/index.js +13 -0
- package/dist/signing/capabilities/index.js.map +1 -0
- package/dist/signing/capabilities/personal-signer.d.ts +7 -0
- package/dist/signing/capabilities/personal-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/personal-signer.js +35 -0
- package/dist/signing/capabilities/personal-signer.js.map +1 -0
- package/dist/signing/capabilities/rsa-pss-signer.d.ts +7 -0
- package/dist/signing/capabilities/rsa-pss-signer.d.ts.map +1 -0
- package/dist/signing/capabilities/rsa-pss-signer.js +35 -0
- package/dist/signing/capabilities/rsa-pss-signer.js.map +1 -0
- package/dist/signing/index.d.ts +13 -0
- package/dist/signing/index.d.ts.map +1 -0
- package/dist/signing/index.js +5 -0
- package/dist/signing/index.js.map +1 -0
- package/dist/signing/registry.d.ts +36 -0
- package/dist/signing/registry.d.ts.map +1 -0
- package/dist/signing/registry.js +27 -0
- package/dist/signing/registry.js.map +1 -0
- package/dist/signing/signing-error.d.ts +22 -0
- package/dist/signing/signing-error.d.ts.map +1 -0
- package/dist/signing/signing-error.js +17 -0
- package/dist/signing/signing-error.js.map +1 -0
- package/dist/signing/types.d.ts +91 -0
- package/dist/signing/types.d.ts.map +1 -0
- package/dist/signing/types.js +2 -0
- package/dist/signing/types.js.map +1 -0
- package/package.json +6 -5
- package/public/admin/assets/index-COymjGTe.js +3 -0
- package/public/admin/assets/index-CTHU1J8K.css +1 -0
- package/public/admin/index.html +4 -2
- package/public/admin/assets/index-BpDnuS0k.css +0 -1
- package/public/admin/assets/index-By5VUJ-B.js +0 -3
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RpcDispatcher -- Orchestrates JSON-RPC method classification and handler routing.
|
|
3
|
+
*
|
|
4
|
+
* Entry point for the RPC proxy: classifies each method as intercept, passthrough,
|
|
5
|
+
* or unsupported, then delegates to the appropriate handler.
|
|
6
|
+
*
|
|
7
|
+
* Supports both single and batch JSON-RPC 2.0 requests.
|
|
8
|
+
*
|
|
9
|
+
* @see .planning/research/m31-14-rpc-proxy-ARCHITECTURE.md
|
|
10
|
+
*/
|
|
11
|
+
import { jsonRpcError, isNotification, JSON_RPC_ERRORS, } from './json-rpc.js';
|
|
12
|
+
import { classifyMethod } from './method-handlers.js';
|
|
13
|
+
// -- RpcDispatcher -----------------------------------------------------------
|
|
14
|
+
export class RpcDispatcher {
|
|
15
|
+
methodHandlers;
|
|
16
|
+
passthrough;
|
|
17
|
+
constructor(deps) {
|
|
18
|
+
this.methodHandlers = deps.methodHandlers;
|
|
19
|
+
this.passthrough = deps.passthrough;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Dispatch a single JSON-RPC request to the appropriate handler.
|
|
23
|
+
*/
|
|
24
|
+
async dispatch(request, ctx, pipelineDeps) {
|
|
25
|
+
const id = request.id ?? null;
|
|
26
|
+
const classification = classifyMethod(request.method, this.passthrough);
|
|
27
|
+
switch (classification) {
|
|
28
|
+
case 'intercept':
|
|
29
|
+
return this.methodHandlers.handle(request.method, request.params, id, ctx, pipelineDeps);
|
|
30
|
+
case 'passthrough':
|
|
31
|
+
return this.passthrough.forward(request, ctx.network);
|
|
32
|
+
case 'unsupported':
|
|
33
|
+
return jsonRpcError(id, JSON_RPC_ERRORS.METHOD_NOT_FOUND, 'Method not found: ' + request.method);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Dispatch a batch of JSON-RPC requests.
|
|
38
|
+
*
|
|
39
|
+
* All requests are dispatched concurrently via Promise.all.
|
|
40
|
+
* Notifications (requests without `id`) are dispatched for side effects
|
|
41
|
+
* but their responses are filtered from the result per JSON-RPC 2.0 spec.
|
|
42
|
+
*/
|
|
43
|
+
async dispatchBatch(requests, ctx, pipelineDeps) {
|
|
44
|
+
const results = await Promise.all(requests.map(async (request) => ({
|
|
45
|
+
response: await this.dispatch(request, ctx, pipelineDeps),
|
|
46
|
+
isNotification: isNotification(request),
|
|
47
|
+
})));
|
|
48
|
+
// Filter out notification responses per JSON-RPC 2.0 spec
|
|
49
|
+
return results
|
|
50
|
+
.filter((r) => !r.isNotification)
|
|
51
|
+
.map((r) => r.response);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=dispatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/rpc-proxy/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,YAAY,EACZ,cAAc,EACd,eAAe,GAGhB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAatD,+EAA+E;AAE/E,MAAM,OAAO,aAAa;IACP,cAAc,CAAoB;IAClC,WAAW,CAAiB;IAE7C,YAAY,IAAuB;QACjC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CACZ,OAAuB,EACvB,GAAmB,EACnB,YAAiB;QAEjB,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,IAAI,CAAC;QAC9B,MAAM,cAAc,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAExE,QAAQ,cAAc,EAAE,CAAC;YACvB,KAAK,WAAW;gBACd,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,CAC/B,OAAO,CAAC,MAAM,EACd,OAAO,CAAC,MAA+B,EACvC,EAAE,EACF,GAAG,EACH,YAAY,CACb,CAAC;YAEJ,KAAK,aAAa;gBAChB,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YAExD,KAAK,aAAa;gBAChB,OAAO,YAAY,CACjB,EAAE,EACF,eAAe,CAAC,gBAAgB,EAChC,oBAAoB,GAAG,OAAO,CAAC,MAAM,CACtC,CAAC;QACN,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,aAAa,CACjB,QAA0B,EAC1B,GAAmB,EACnB,YAAiB;QAEjB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;YAC/B,QAAQ,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,YAAY,CAAC;YACzD,cAAc,EAAE,cAAc,CAAC,OAAO,CAAC;SACxC,CAAC,CAAC,CACJ,CAAC;QAEF,0DAA0D;QAC1D,OAAO,OAAO;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;CACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC Proxy module barrel export.
|
|
3
|
+
*
|
|
4
|
+
* Core engine for the EVM JSON-RPC proxy that intercepts signing methods
|
|
5
|
+
* and proxies read methods to upstream RPC endpoints.
|
|
6
|
+
*/
|
|
7
|
+
export { type JsonRpcRequest, type JsonRpcResponse, type JsonRpcSuccessResponse, type JsonRpcErrorResponse, type JsonRpcError, type ParseResult, jsonRpcSuccess, jsonRpcError, parseJsonRpcBody, isNotification, JSON_RPC_ERRORS, } from './json-rpc.js';
|
|
8
|
+
export { RpcTransactionAdapter, toHexChainId, hexToDecimal, type EthTransactionParams, type RpcTransactionRequest, } from './tx-adapter.js';
|
|
9
|
+
export { CompletionWaiter } from './completion-waiter.js';
|
|
10
|
+
export { SyncPipelineExecutor } from './sync-pipeline.js';
|
|
11
|
+
export { NonceTracker } from './nonce-tracker.js';
|
|
12
|
+
export { RpcPassthrough, PASSTHROUGH_METHODS } from './passthrough.js';
|
|
13
|
+
export { RpcMethodHandlers, classifyMethod, INTERCEPT_METHODS, type HandlerContext, } from './method-handlers.js';
|
|
14
|
+
export { RpcDispatcher, type RpcDispatcherDeps } from './dispatcher.js';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rpc-proxy/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,qBAAqB,EACrB,YAAY,EACZ,YAAY,EACZ,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,GAC3B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvE,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,KAAK,cAAc,GACpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC Proxy module barrel export.
|
|
3
|
+
*
|
|
4
|
+
* Core engine for the EVM JSON-RPC proxy that intercepts signing methods
|
|
5
|
+
* and proxies read methods to upstream RPC endpoints.
|
|
6
|
+
*/
|
|
7
|
+
export { jsonRpcSuccess, jsonRpcError, parseJsonRpcBody, isNotification, JSON_RPC_ERRORS, } from './json-rpc.js';
|
|
8
|
+
export { RpcTransactionAdapter, toHexChainId, hexToDecimal, } from './tx-adapter.js';
|
|
9
|
+
export { CompletionWaiter } from './completion-waiter.js';
|
|
10
|
+
export { SyncPipelineExecutor } from './sync-pipeline.js';
|
|
11
|
+
export { NonceTracker } from './nonce-tracker.js';
|
|
12
|
+
export { RpcPassthrough, PASSTHROUGH_METHODS } from './passthrough.js';
|
|
13
|
+
export { RpcMethodHandlers, classifyMethod, INTERCEPT_METHODS, } from './method-handlers.js';
|
|
14
|
+
export { RpcDispatcher } from './dispatcher.js';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rpc-proxy/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAOL,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,qBAAqB,EACrB,YAAY,EACZ,YAAY,GAGb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvE,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAElB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,aAAa,EAA0B,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-RPC 2.0 protocol utilities for the RPC proxy.
|
|
3
|
+
*
|
|
4
|
+
* Provides request parsing, response building, and standard error codes
|
|
5
|
+
* following the JSON-RPC 2.0 specification (https://www.jsonrpc.org/specification).
|
|
6
|
+
*
|
|
7
|
+
* Key spec compliance (Pitfall 9):
|
|
8
|
+
* - `id` type is preserved exactly (number, string, or null)
|
|
9
|
+
* - Success response has `result` but NOT `error`
|
|
10
|
+
* - Error response has `error` but NOT `result`
|
|
11
|
+
* - Notification = request without `id` field (not same as id=null)
|
|
12
|
+
*
|
|
13
|
+
* @see .planning/research/m31-14-rpc-proxy-PITFALLS.md (Pitfall 9)
|
|
14
|
+
*/
|
|
15
|
+
export interface JsonRpcRequest {
|
|
16
|
+
jsonrpc: '2.0';
|
|
17
|
+
method: string;
|
|
18
|
+
params?: unknown[];
|
|
19
|
+
id?: string | number | null;
|
|
20
|
+
}
|
|
21
|
+
export interface JsonRpcError {
|
|
22
|
+
code: number;
|
|
23
|
+
message: string;
|
|
24
|
+
data?: unknown;
|
|
25
|
+
}
|
|
26
|
+
export interface JsonRpcSuccessResponse {
|
|
27
|
+
jsonrpc: '2.0';
|
|
28
|
+
id: string | number | null;
|
|
29
|
+
result: unknown;
|
|
30
|
+
}
|
|
31
|
+
export interface JsonRpcErrorResponse {
|
|
32
|
+
jsonrpc: '2.0';
|
|
33
|
+
id: string | number | null;
|
|
34
|
+
error: JsonRpcError;
|
|
35
|
+
}
|
|
36
|
+
export type JsonRpcResponse = JsonRpcSuccessResponse | JsonRpcErrorResponse;
|
|
37
|
+
export declare const JSON_RPC_ERRORS: {
|
|
38
|
+
readonly PARSE_ERROR: -32700;
|
|
39
|
+
readonly INVALID_REQUEST: -32600;
|
|
40
|
+
readonly METHOD_NOT_FOUND: -32601;
|
|
41
|
+
readonly INVALID_PARAMS: -32602;
|
|
42
|
+
readonly INTERNAL_ERROR: -32603;
|
|
43
|
+
readonly SERVER_ERROR: -32000;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Build a JSON-RPC 2.0 success response.
|
|
47
|
+
* Result and error are mutually exclusive per spec.
|
|
48
|
+
*/
|
|
49
|
+
export declare function jsonRpcSuccess(id: string | number | null, result: unknown): JsonRpcSuccessResponse;
|
|
50
|
+
/**
|
|
51
|
+
* Build a JSON-RPC 2.0 error response.
|
|
52
|
+
* Result and error are mutually exclusive per spec.
|
|
53
|
+
*/
|
|
54
|
+
export declare function jsonRpcError(id: string | number | null, code: number, message: string, data?: unknown): JsonRpcErrorResponse;
|
|
55
|
+
export type ParseResult = {
|
|
56
|
+
type: 'single';
|
|
57
|
+
request: JsonRpcRequest;
|
|
58
|
+
} | {
|
|
59
|
+
type: 'batch';
|
|
60
|
+
requests: JsonRpcRequest[];
|
|
61
|
+
} | {
|
|
62
|
+
type: 'error';
|
|
63
|
+
response: JsonRpcErrorResponse;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Parse a JSON-RPC 2.0 request body (already JSON-parsed).
|
|
67
|
+
*
|
|
68
|
+
* Returns single request, batch of requests, or error response.
|
|
69
|
+
* Validates `jsonrpc === '2.0'` and `method` is string.
|
|
70
|
+
* Does NOT validate `params` (method handlers do that).
|
|
71
|
+
*/
|
|
72
|
+
export declare function parseJsonRpcBody(body: unknown): ParseResult;
|
|
73
|
+
/**
|
|
74
|
+
* A notification is a request without an `id` field.
|
|
75
|
+
* Note: `id: null` is valid and is NOT a notification.
|
|
76
|
+
*/
|
|
77
|
+
export declare function isNotification(req: JsonRpcRequest): boolean;
|
|
78
|
+
//# sourceMappingURL=json-rpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-rpc.d.ts","sourceRoot":"","sources":["../../src/rpc-proxy/json-rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,MAAM,eAAe,GAAG,sBAAsB,GAAG,oBAAoB,CAAC;AAI5E,eAAO,MAAM,eAAe;;;;;;;CAOlB,CAAC;AAIX;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAC1B,MAAM,EAAE,OAAO,GACd,sBAAsB,CAExB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,OAAO,GACb,oBAAoB,CAMtB;AAID,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAItD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,CA8C3D;AAID;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAE3D"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-RPC 2.0 protocol utilities for the RPC proxy.
|
|
3
|
+
*
|
|
4
|
+
* Provides request parsing, response building, and standard error codes
|
|
5
|
+
* following the JSON-RPC 2.0 specification (https://www.jsonrpc.org/specification).
|
|
6
|
+
*
|
|
7
|
+
* Key spec compliance (Pitfall 9):
|
|
8
|
+
* - `id` type is preserved exactly (number, string, or null)
|
|
9
|
+
* - Success response has `result` but NOT `error`
|
|
10
|
+
* - Error response has `error` but NOT `result`
|
|
11
|
+
* - Notification = request without `id` field (not same as id=null)
|
|
12
|
+
*
|
|
13
|
+
* @see .planning/research/m31-14-rpc-proxy-PITFALLS.md (Pitfall 9)
|
|
14
|
+
*/
|
|
15
|
+
// ── Error Codes ───────────────────────────────────────────────────
|
|
16
|
+
export const JSON_RPC_ERRORS = {
|
|
17
|
+
PARSE_ERROR: -32700,
|
|
18
|
+
INVALID_REQUEST: -32600,
|
|
19
|
+
METHOD_NOT_FOUND: -32601,
|
|
20
|
+
INVALID_PARAMS: -32602,
|
|
21
|
+
INTERNAL_ERROR: -32603,
|
|
22
|
+
SERVER_ERROR: -32000,
|
|
23
|
+
};
|
|
24
|
+
// ── Response Builders ─────────────────────────────────────────────
|
|
25
|
+
/**
|
|
26
|
+
* Build a JSON-RPC 2.0 success response.
|
|
27
|
+
* Result and error are mutually exclusive per spec.
|
|
28
|
+
*/
|
|
29
|
+
export function jsonRpcSuccess(id, result) {
|
|
30
|
+
return { jsonrpc: '2.0', id, result };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Build a JSON-RPC 2.0 error response.
|
|
34
|
+
* Result and error are mutually exclusive per spec.
|
|
35
|
+
*/
|
|
36
|
+
export function jsonRpcError(id, code, message, data) {
|
|
37
|
+
const error = { code, message };
|
|
38
|
+
if (data !== undefined) {
|
|
39
|
+
error.data = data;
|
|
40
|
+
}
|
|
41
|
+
return { jsonrpc: '2.0', id, error };
|
|
42
|
+
}
|
|
43
|
+
// ── Body Parsing ──────────────────────────────────────────────────
|
|
44
|
+
/**
|
|
45
|
+
* Parse a JSON-RPC 2.0 request body (already JSON-parsed).
|
|
46
|
+
*
|
|
47
|
+
* Returns single request, batch of requests, or error response.
|
|
48
|
+
* Validates `jsonrpc === '2.0'` and `method` is string.
|
|
49
|
+
* Does NOT validate `params` (method handlers do that).
|
|
50
|
+
*/
|
|
51
|
+
export function parseJsonRpcBody(body) {
|
|
52
|
+
if (body === null || body === undefined || typeof body !== 'object') {
|
|
53
|
+
return {
|
|
54
|
+
type: 'error',
|
|
55
|
+
response: jsonRpcError(null, JSON_RPC_ERRORS.INVALID_REQUEST, 'Invalid Request'),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// Batch request (array)
|
|
59
|
+
if (Array.isArray(body)) {
|
|
60
|
+
if (body.length === 0) {
|
|
61
|
+
return {
|
|
62
|
+
type: 'error',
|
|
63
|
+
response: jsonRpcError(null, JSON_RPC_ERRORS.INVALID_REQUEST, 'Empty batch array'),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const requests = [];
|
|
67
|
+
for (const item of body) {
|
|
68
|
+
const validated = validateSingleRequest(item);
|
|
69
|
+
if (!validated) {
|
|
70
|
+
// Skip invalid items in batch (spec allows partial processing)
|
|
71
|
+
// but for simplicity, return error for any invalid item
|
|
72
|
+
return {
|
|
73
|
+
type: 'error',
|
|
74
|
+
response: jsonRpcError(null, JSON_RPC_ERRORS.INVALID_REQUEST, 'Invalid Request in batch'),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
requests.push(validated);
|
|
78
|
+
}
|
|
79
|
+
return { type: 'batch', requests };
|
|
80
|
+
}
|
|
81
|
+
// Single request
|
|
82
|
+
const validated = validateSingleRequest(body);
|
|
83
|
+
if (!validated) {
|
|
84
|
+
return {
|
|
85
|
+
type: 'error',
|
|
86
|
+
response: jsonRpcError(null, JSON_RPC_ERRORS.INVALID_REQUEST, 'Invalid Request'),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return { type: 'single', request: validated };
|
|
90
|
+
}
|
|
91
|
+
// ── Notification Detection ────────────────────────────────────────
|
|
92
|
+
/**
|
|
93
|
+
* A notification is a request without an `id` field.
|
|
94
|
+
* Note: `id: null` is valid and is NOT a notification.
|
|
95
|
+
*/
|
|
96
|
+
export function isNotification(req) {
|
|
97
|
+
return req.id === undefined;
|
|
98
|
+
}
|
|
99
|
+
// ── Helpers ───────────────────────────────────────────────────────
|
|
100
|
+
function validateSingleRequest(obj) {
|
|
101
|
+
if (obj === null || obj === undefined || typeof obj !== 'object' || Array.isArray(obj)) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
const rec = obj;
|
|
105
|
+
if (rec.jsonrpc !== '2.0') {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
if (typeof rec.method !== 'string') {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
const request = {
|
|
112
|
+
jsonrpc: '2.0',
|
|
113
|
+
method: rec.method,
|
|
114
|
+
};
|
|
115
|
+
if (rec.params !== undefined) {
|
|
116
|
+
request.params = rec.params;
|
|
117
|
+
}
|
|
118
|
+
if ('id' in rec) {
|
|
119
|
+
request.id = rec.id;
|
|
120
|
+
}
|
|
121
|
+
return request;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=json-rpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-rpc.js","sourceRoot":"","sources":["../../src/rpc-proxy/json-rpc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC Method Handlers -- Signing method intercept for the RPC proxy.
|
|
3
|
+
*
|
|
4
|
+
* Routes intercepted JSON-RPC methods to the appropriate WAIaaS pipeline:
|
|
5
|
+
* - eth_sendTransaction → 6-stage pipeline via SyncPipelineExecutor
|
|
6
|
+
* - eth_signTransaction → sign-only pipeline
|
|
7
|
+
* - personal_sign, eth_sign → sign-message pipeline (personal)
|
|
8
|
+
* - eth_signTypedData_v4 → sign-message pipeline (typedData)
|
|
9
|
+
* - eth_accounts → session wallet address
|
|
10
|
+
* - eth_chainId → URL-derived hex chain ID
|
|
11
|
+
* - eth_sendRawTransaction → explicit rejection (SIGN-07)
|
|
12
|
+
*
|
|
13
|
+
* @see .planning/research/m31-14-rpc-proxy-ARCHITECTURE.md
|
|
14
|
+
*/
|
|
15
|
+
import { type JsonRpcResponse } from './json-rpc.js';
|
|
16
|
+
import type { RpcTransactionAdapter } from './tx-adapter.js';
|
|
17
|
+
import type { SyncPipelineExecutor } from './sync-pipeline.js';
|
|
18
|
+
import type { NonceTracker } from './nonce-tracker.js';
|
|
19
|
+
import type { RpcPassthrough } from './passthrough.js';
|
|
20
|
+
export declare const INTERCEPT_METHODS: Set<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Classify a JSON-RPC method into intercept, passthrough, or unsupported.
|
|
23
|
+
*/
|
|
24
|
+
export declare function classifyMethod(method: string, passthrough: RpcPassthrough): 'intercept' | 'passthrough' | 'unsupported';
|
|
25
|
+
export interface HandlerContext {
|
|
26
|
+
walletId: string;
|
|
27
|
+
walletAddress: string;
|
|
28
|
+
chainId: number;
|
|
29
|
+
network: string;
|
|
30
|
+
chain: string;
|
|
31
|
+
sessionId?: string;
|
|
32
|
+
}
|
|
33
|
+
export declare class RpcMethodHandlers {
|
|
34
|
+
private syncPipeline;
|
|
35
|
+
private txAdapter;
|
|
36
|
+
constructor(syncPipeline: SyncPipelineExecutor, txAdapter: RpcTransactionAdapter, _nonceTracker: NonceTracker);
|
|
37
|
+
/**
|
|
38
|
+
* Handle an intercepted JSON-RPC method.
|
|
39
|
+
*
|
|
40
|
+
* @param method - JSON-RPC method name
|
|
41
|
+
* @param params - Method parameters
|
|
42
|
+
* @param id - Request id (preserved in response)
|
|
43
|
+
* @param ctx - Handler context (wallet, chain, session)
|
|
44
|
+
* @param deps - Pipeline dependencies
|
|
45
|
+
* @returns JSON-RPC response
|
|
46
|
+
*/
|
|
47
|
+
handle(method: string, params: unknown[] | undefined, id: string | number | null, ctx: HandlerContext, deps: any): Promise<JsonRpcResponse>;
|
|
48
|
+
private handleEthSendTransaction;
|
|
49
|
+
private handleEthSignTransaction;
|
|
50
|
+
private handlePersonalSign;
|
|
51
|
+
private handleEthSign;
|
|
52
|
+
private handleEthSignTypedDataV4;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=method-handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"method-handlers.d.ts","sourceRoot":"","sources":["../../src/rpc-proxy/method-handlers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAMvD,eAAO,MAAM,iBAAiB,aAW5B,CAAC;AAIH;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,cAAc,GAC1B,WAAW,GAAG,aAAa,GAAG,aAAa,CAI7C;AAID,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,SAAS;gBADT,YAAY,EAAE,oBAAoB,EAClC,SAAS,EAAE,qBAAqB,EACxC,aAAa,EAAE,YAAY;IAG7B;;;;;;;;;OASG;IACG,MAAM,CACV,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,EAC7B,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAC1B,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,GAAG,GACR,OAAO,CAAC,eAAe,CAAC;YAgDb,wBAAwB;YAiCxB,wBAAwB;YA2BxB,kBAAkB;YAyBlB,aAAa;YAyBb,wBAAwB;CAwBvC"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC Method Handlers -- Signing method intercept for the RPC proxy.
|
|
3
|
+
*
|
|
4
|
+
* Routes intercepted JSON-RPC methods to the appropriate WAIaaS pipeline:
|
|
5
|
+
* - eth_sendTransaction → 6-stage pipeline via SyncPipelineExecutor
|
|
6
|
+
* - eth_signTransaction → sign-only pipeline
|
|
7
|
+
* - personal_sign, eth_sign → sign-message pipeline (personal)
|
|
8
|
+
* - eth_signTypedData_v4 → sign-message pipeline (typedData)
|
|
9
|
+
* - eth_accounts → session wallet address
|
|
10
|
+
* - eth_chainId → URL-derived hex chain ID
|
|
11
|
+
* - eth_sendRawTransaction → explicit rejection (SIGN-07)
|
|
12
|
+
*
|
|
13
|
+
* @see .planning/research/m31-14-rpc-proxy-ARCHITECTURE.md
|
|
14
|
+
*/
|
|
15
|
+
import { jsonRpcSuccess, jsonRpcError, JSON_RPC_ERRORS, } from './json-rpc.js';
|
|
16
|
+
import { toHexChainId } from './tx-adapter.js';
|
|
17
|
+
import { executeSignOnly } from '../pipeline/sign-only.js';
|
|
18
|
+
import { executeSignMessage } from '../pipeline/sign-message.js';
|
|
19
|
+
// ── Intercept Methods ─────────────────────────────────────────────
|
|
20
|
+
export const INTERCEPT_METHODS = new Set([
|
|
21
|
+
'eth_sendTransaction',
|
|
22
|
+
'eth_signTransaction',
|
|
23
|
+
'eth_accounts',
|
|
24
|
+
'eth_requestAccounts',
|
|
25
|
+
'eth_chainId',
|
|
26
|
+
'net_version',
|
|
27
|
+
'personal_sign',
|
|
28
|
+
'eth_sign',
|
|
29
|
+
'eth_signTypedData_v4',
|
|
30
|
+
'eth_sendRawTransaction',
|
|
31
|
+
]);
|
|
32
|
+
// ── Method Classification ─────────────────────────────────────────
|
|
33
|
+
/**
|
|
34
|
+
* Classify a JSON-RPC method into intercept, passthrough, or unsupported.
|
|
35
|
+
*/
|
|
36
|
+
export function classifyMethod(method, passthrough) {
|
|
37
|
+
if (INTERCEPT_METHODS.has(method))
|
|
38
|
+
return 'intercept';
|
|
39
|
+
if (passthrough.isPassthrough(method))
|
|
40
|
+
return 'passthrough';
|
|
41
|
+
return 'unsupported';
|
|
42
|
+
}
|
|
43
|
+
// ── RpcMethodHandlers ─────────────────────────────────────────────
|
|
44
|
+
export class RpcMethodHandlers {
|
|
45
|
+
syncPipeline;
|
|
46
|
+
txAdapter;
|
|
47
|
+
constructor(syncPipeline, txAdapter, _nonceTracker) {
|
|
48
|
+
this.syncPipeline = syncPipeline;
|
|
49
|
+
this.txAdapter = txAdapter;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Handle an intercepted JSON-RPC method.
|
|
53
|
+
*
|
|
54
|
+
* @param method - JSON-RPC method name
|
|
55
|
+
* @param params - Method parameters
|
|
56
|
+
* @param id - Request id (preserved in response)
|
|
57
|
+
* @param ctx - Handler context (wallet, chain, session)
|
|
58
|
+
* @param deps - Pipeline dependencies
|
|
59
|
+
* @returns JSON-RPC response
|
|
60
|
+
*/
|
|
61
|
+
async handle(method, params, id, ctx, deps) {
|
|
62
|
+
switch (method) {
|
|
63
|
+
// ── Account Discovery ─────────────────────────
|
|
64
|
+
case 'eth_accounts':
|
|
65
|
+
case 'eth_requestAccounts':
|
|
66
|
+
return jsonRpcSuccess(id, [ctx.walletAddress]);
|
|
67
|
+
// ── Chain Identity ────────────────────────────
|
|
68
|
+
case 'eth_chainId':
|
|
69
|
+
return jsonRpcSuccess(id, toHexChainId(ctx.chainId));
|
|
70
|
+
case 'net_version':
|
|
71
|
+
return jsonRpcSuccess(id, ctx.chainId.toString());
|
|
72
|
+
// ── Transaction Signing + Submission ──────────
|
|
73
|
+
case 'eth_sendTransaction':
|
|
74
|
+
return this.handleEthSendTransaction(params, id, ctx, deps);
|
|
75
|
+
// ── Transaction Signing (no broadcast) ────────
|
|
76
|
+
case 'eth_signTransaction':
|
|
77
|
+
return this.handleEthSignTransaction(params, id, ctx, deps);
|
|
78
|
+
// ── Message Signing ───────────────────────────
|
|
79
|
+
case 'personal_sign':
|
|
80
|
+
return this.handlePersonalSign(params, id, ctx, deps);
|
|
81
|
+
case 'eth_sign':
|
|
82
|
+
return this.handleEthSign(params, id, ctx, deps);
|
|
83
|
+
case 'eth_signTypedData_v4':
|
|
84
|
+
return this.handleEthSignTypedDataV4(params, id, ctx, deps);
|
|
85
|
+
// ── Explicit Rejection ────────────────────────
|
|
86
|
+
case 'eth_sendRawTransaction':
|
|
87
|
+
return jsonRpcError(id, JSON_RPC_ERRORS.INVALID_PARAMS, 'eth_sendRawTransaction is not supported. Use eth_sendTransaction instead — WAIaaS signs transactions internally.');
|
|
88
|
+
// ── Unsupported ───────────────────────────────
|
|
89
|
+
default:
|
|
90
|
+
return jsonRpcError(id, JSON_RPC_ERRORS.METHOD_NOT_FOUND, `Method ${method} not supported`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ── Private Handlers ──────────────────────────────────────────
|
|
94
|
+
async handleEthSendTransaction(params, id, ctx, deps) {
|
|
95
|
+
try {
|
|
96
|
+
const txParams = (params?.[0] ?? {});
|
|
97
|
+
const request = this.txAdapter.convert(txParams, ctx.network);
|
|
98
|
+
// Build pipeline context
|
|
99
|
+
const pipelineCtx = {
|
|
100
|
+
...deps,
|
|
101
|
+
walletId: ctx.walletId,
|
|
102
|
+
resolvedNetwork: ctx.network,
|
|
103
|
+
request,
|
|
104
|
+
txId: '', // Will be generated by stage1Validate
|
|
105
|
+
sessionId: ctx.sessionId,
|
|
106
|
+
};
|
|
107
|
+
const txHash = await this.syncPipeline.execute(pipelineCtx);
|
|
108
|
+
return jsonRpcSuccess(id, txHash);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
const message = err instanceof Error ? err.message : 'Transaction execution failed';
|
|
112
|
+
// ASYNC-04: Include txId in timeout error data for client recovery
|
|
113
|
+
const txIdMatch = message.match(/Transaction ([a-f0-9-]+) timed out/);
|
|
114
|
+
if (txIdMatch) {
|
|
115
|
+
return jsonRpcError(id, JSON_RPC_ERRORS.SERVER_ERROR, message, { txId: txIdMatch[1] });
|
|
116
|
+
}
|
|
117
|
+
return jsonRpcError(id, JSON_RPC_ERRORS.SERVER_ERROR, message);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async handleEthSignTransaction(params, id, ctx, deps) {
|
|
121
|
+
try {
|
|
122
|
+
const txParams = (params?.[0] ?? {});
|
|
123
|
+
// Build a serialized unsigned transaction string for sign-only pipeline
|
|
124
|
+
// The sign-only pipeline expects a serialized transaction hex
|
|
125
|
+
const txHex = JSON.stringify(txParams);
|
|
126
|
+
const result = await executeSignOnly(deps, ctx.walletId, { transaction: txHex, chain: ctx.chain, network: ctx.network }, ctx.sessionId);
|
|
127
|
+
return jsonRpcSuccess(id, result.signedTransaction);
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
const message = err instanceof Error ? err.message : 'Transaction signing failed';
|
|
131
|
+
return jsonRpcError(id, JSON_RPC_ERRORS.SERVER_ERROR, message);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async handlePersonalSign(params, id, ctx, deps) {
|
|
135
|
+
try {
|
|
136
|
+
// personal_sign params: [message, address]
|
|
137
|
+
const message = params?.[0] ?? '';
|
|
138
|
+
const result = await executeSignMessage(deps, ctx.walletId, ctx.chain, { signType: 'personal', message }, ctx.sessionId);
|
|
139
|
+
return jsonRpcSuccess(id, result.signature);
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
const message = err instanceof Error ? err.message : 'Message signing failed';
|
|
143
|
+
return jsonRpcError(id, JSON_RPC_ERRORS.SERVER_ERROR, message);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async handleEthSign(params, id, ctx, deps) {
|
|
147
|
+
try {
|
|
148
|
+
// eth_sign params: [address, message] -- reversed from personal_sign!
|
|
149
|
+
const msgData = params?.[1] ?? '';
|
|
150
|
+
const result = await executeSignMessage(deps, ctx.walletId, ctx.chain, { signType: 'personal', message: msgData }, ctx.sessionId);
|
|
151
|
+
return jsonRpcSuccess(id, result.signature);
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
const message = err instanceof Error ? err.message : 'Message signing failed';
|
|
155
|
+
return jsonRpcError(id, JSON_RPC_ERRORS.SERVER_ERROR, message);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
async handleEthSignTypedDataV4(params, id, ctx, deps) {
|
|
159
|
+
try {
|
|
160
|
+
// eth_signTypedData_v4 params: [address, typedDataJsonString]
|
|
161
|
+
const typedDataJson = params?.[1] ?? '';
|
|
162
|
+
const result = await executeSignMessage(deps, ctx.walletId, ctx.chain, { signType: 'typedData', message: typedDataJson }, ctx.sessionId);
|
|
163
|
+
return jsonRpcSuccess(id, result.signature);
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
const message = err instanceof Error ? err.message : 'Typed data signing failed';
|
|
167
|
+
return jsonRpcError(id, JSON_RPC_ERRORS.SERVER_ERROR, message);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=method-handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"method-handlers.js","sourceRoot":"","sources":["../../src/rpc-proxy/method-handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NonceTracker -- Local nonce management for sequential eth_sendTransaction.
|
|
3
|
+
*
|
|
4
|
+
* Addresses Pitfall 4 (Forge Script Multi-TX Nonce): When Forge sends
|
|
5
|
+
* multiple transactions in rapid succession, each needs a unique nonce.
|
|
6
|
+
* The on-chain nonce may not have updated yet, so we track locally.
|
|
7
|
+
*
|
|
8
|
+
* Per-address tracking with case-insensitive comparison.
|
|
9
|
+
*
|
|
10
|
+
* @see .planning/research/m31-14-rpc-proxy-PITFALLS.md (Pitfall 4)
|
|
11
|
+
*/
|
|
12
|
+
export declare class NonceTracker {
|
|
13
|
+
private tracker;
|
|
14
|
+
/**
|
|
15
|
+
* Get the next nonce for an address.
|
|
16
|
+
* Returns max(onchainNonce, localNextNonce) and increments local counter.
|
|
17
|
+
*/
|
|
18
|
+
getNextNonce(address: string, onchainNonce: number): number;
|
|
19
|
+
/**
|
|
20
|
+
* Confirm a nonce has been included on-chain.
|
|
21
|
+
* Removes from pending set.
|
|
22
|
+
*/
|
|
23
|
+
confirmNonce(address: string, nonce: number): void;
|
|
24
|
+
/**
|
|
25
|
+
* Rollback a nonce allocation (transaction failed before submission).
|
|
26
|
+
* Removes from pending and recalculates nextNonce.
|
|
27
|
+
*/
|
|
28
|
+
rollbackNonce(address: string, nonce: number): void;
|
|
29
|
+
/**
|
|
30
|
+
* Get adjusted transaction count for eth_getTransactionCount('pending') interception.
|
|
31
|
+
* Returns max of on-chain pending count and local next nonce.
|
|
32
|
+
*/
|
|
33
|
+
getAdjustedTransactionCount(address: string, onchainPendingCount: number): number;
|
|
34
|
+
/**
|
|
35
|
+
* Clear all tracking state.
|
|
36
|
+
*/
|
|
37
|
+
clear(): void;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=nonce-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nonce-tracker.d.ts","sourceRoot":"","sources":["../../src/rpc-proxy/nonce-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAmC;IAElD;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM;IAgB3D;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAQlD;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAgBnD;;;OAGG;IACH,2BAA2B,CAAC,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,MAAM;IAOjF;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
|