@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,80 @@
|
|
|
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
|
+
// ── NonceTracker ──────────────────────────────────────────────────
|
|
13
|
+
export class NonceTracker {
|
|
14
|
+
tracker = new Map();
|
|
15
|
+
/**
|
|
16
|
+
* Get the next nonce for an address.
|
|
17
|
+
* Returns max(onchainNonce, localNextNonce) and increments local counter.
|
|
18
|
+
*/
|
|
19
|
+
getNextNonce(address, onchainNonce) {
|
|
20
|
+
const key = address.toLowerCase();
|
|
21
|
+
let state = this.tracker.get(key);
|
|
22
|
+
if (!state) {
|
|
23
|
+
state = { nextNonce: onchainNonce, pending: new Set() };
|
|
24
|
+
this.tracker.set(key, state);
|
|
25
|
+
}
|
|
26
|
+
// Use max of on-chain and local (on-chain may have advanced)
|
|
27
|
+
const nonce = Math.max(onchainNonce, state.nextNonce);
|
|
28
|
+
state.nextNonce = nonce + 1;
|
|
29
|
+
state.pending.add(nonce);
|
|
30
|
+
return nonce;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Confirm a nonce has been included on-chain.
|
|
34
|
+
* Removes from pending set.
|
|
35
|
+
*/
|
|
36
|
+
confirmNonce(address, nonce) {
|
|
37
|
+
const key = address.toLowerCase();
|
|
38
|
+
const state = this.tracker.get(key);
|
|
39
|
+
if (state) {
|
|
40
|
+
state.pending.delete(nonce);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Rollback a nonce allocation (transaction failed before submission).
|
|
45
|
+
* Removes from pending and recalculates nextNonce.
|
|
46
|
+
*/
|
|
47
|
+
rollbackNonce(address, nonce) {
|
|
48
|
+
const key = address.toLowerCase();
|
|
49
|
+
const state = this.tracker.get(key);
|
|
50
|
+
if (!state)
|
|
51
|
+
return;
|
|
52
|
+
state.pending.delete(nonce);
|
|
53
|
+
// Recalculate nextNonce: max of remaining pending + 1, or the rolled-back nonce
|
|
54
|
+
if (state.pending.size === 0) {
|
|
55
|
+
state.nextNonce = nonce;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
const maxPending = Math.max(...state.pending);
|
|
59
|
+
state.nextNonce = maxPending + 1;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get adjusted transaction count for eth_getTransactionCount('pending') interception.
|
|
64
|
+
* Returns max of on-chain pending count and local next nonce.
|
|
65
|
+
*/
|
|
66
|
+
getAdjustedTransactionCount(address, onchainPendingCount) {
|
|
67
|
+
const key = address.toLowerCase();
|
|
68
|
+
const state = this.tracker.get(key);
|
|
69
|
+
if (!state)
|
|
70
|
+
return onchainPendingCount;
|
|
71
|
+
return Math.max(onchainPendingCount, state.nextNonce);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Clear all tracking state.
|
|
75
|
+
*/
|
|
76
|
+
clear() {
|
|
77
|
+
this.tracker.clear();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=nonce-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nonce-tracker.js","sourceRoot":"","sources":["../../src/rpc-proxy/nonce-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,qEAAqE;AAErE,MAAM,OAAO,YAAY;IACf,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAC;IAElD;;;OAGG;IACH,YAAY,CAAC,OAAe,EAAE,YAAoB;QAChD,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QAClC,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;YACxD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/B,CAAC;QAED,6DAA6D;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QACtD,KAAK,CAAC,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;QAC5B,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,OAAe,EAAE,KAAa;QACzC,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,OAAe,EAAE,KAAa;QAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK;YAAE,OAAO;QAEnB,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAE5B,gFAAgF;QAChF,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC7B,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;YAC9C,KAAK,CAAC,SAAS,GAAG,UAAU,GAAG,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,2BAA2B,CAAC,OAAe,EAAE,mBAA2B;QACtE,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK;YAAE,OAAO,mBAAmB,CAAC;QACvC,OAAO,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RpcPassthrough -- Read method proxying to upstream RPC via RpcPool.
|
|
3
|
+
*
|
|
4
|
+
* All read-only EVM JSON-RPC methods are forwarded directly to the
|
|
5
|
+
* upstream RPC endpoint. Signing and state-changing methods are NOT
|
|
6
|
+
* included -- those are handled by RpcMethodHandlers.
|
|
7
|
+
*
|
|
8
|
+
* PASS-01: Read methods pass through to upstream RPC
|
|
9
|
+
* PASS-02: Unsupported methods return -32601 (handled by caller)
|
|
10
|
+
*
|
|
11
|
+
* @see .planning/research/m31-14-rpc-proxy-ARCHITECTURE.md
|
|
12
|
+
*/
|
|
13
|
+
import type { RpcPool } from '@waiaas/core';
|
|
14
|
+
import { type JsonRpcRequest, type JsonRpcResponse } from './json-rpc.js';
|
|
15
|
+
/**
|
|
16
|
+
* Set of all read-only EVM JSON-RPC methods that should be proxied
|
|
17
|
+
* directly to the upstream RPC endpoint.
|
|
18
|
+
*/
|
|
19
|
+
export declare const PASSTHROUGH_METHODS: Set<string>;
|
|
20
|
+
export declare class RpcPassthrough {
|
|
21
|
+
private rpcPool;
|
|
22
|
+
constructor(rpcPool: RpcPool);
|
|
23
|
+
/**
|
|
24
|
+
* Check if a method should be passthrough-proxied.
|
|
25
|
+
*/
|
|
26
|
+
isPassthrough(method: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Forward a JSON-RPC request to the upstream RPC endpoint.
|
|
29
|
+
* Preserves the original request id in the response.
|
|
30
|
+
*
|
|
31
|
+
* @param request - The JSON-RPC request to forward
|
|
32
|
+
* @param network - Network slug for RpcPool URL resolution
|
|
33
|
+
* @returns JSON-RPC response (success or error)
|
|
34
|
+
*/
|
|
35
|
+
forward(request: JsonRpcRequest, network: string): Promise<JsonRpcResponse>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=passthrough.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passthrough.d.ts","sourceRoot":"","sources":["../../src/rpc-proxy/passthrough.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAIvB;;;GAGG;AACH,eAAO,MAAM,mBAAmB,aAoB9B,CAAC;AAIH,qBAAa,cAAc;IACb,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,OAAO;IAEpC;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAItC;;;;;;;OAOG;IACG,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAmClF"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RpcPassthrough -- Read method proxying to upstream RPC via RpcPool.
|
|
3
|
+
*
|
|
4
|
+
* All read-only EVM JSON-RPC methods are forwarded directly to the
|
|
5
|
+
* upstream RPC endpoint. Signing and state-changing methods are NOT
|
|
6
|
+
* included -- those are handled by RpcMethodHandlers.
|
|
7
|
+
*
|
|
8
|
+
* PASS-01: Read methods pass through to upstream RPC
|
|
9
|
+
* PASS-02: Unsupported methods return -32601 (handled by caller)
|
|
10
|
+
*
|
|
11
|
+
* @see .planning/research/m31-14-rpc-proxy-ARCHITECTURE.md
|
|
12
|
+
*/
|
|
13
|
+
import { jsonRpcError, JSON_RPC_ERRORS, } from './json-rpc.js';
|
|
14
|
+
// ── Passthrough Methods ───────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Set of all read-only EVM JSON-RPC methods that should be proxied
|
|
17
|
+
* directly to the upstream RPC endpoint.
|
|
18
|
+
*/
|
|
19
|
+
export const PASSTHROUGH_METHODS = new Set([
|
|
20
|
+
'eth_call',
|
|
21
|
+
'eth_getBalance',
|
|
22
|
+
'eth_blockNumber',
|
|
23
|
+
'eth_getBlockByNumber',
|
|
24
|
+
'eth_getBlockByHash',
|
|
25
|
+
'eth_getTransactionByHash',
|
|
26
|
+
'eth_getTransactionReceipt',
|
|
27
|
+
'eth_estimateGas',
|
|
28
|
+
'eth_gasPrice',
|
|
29
|
+
'eth_feeHistory',
|
|
30
|
+
'eth_maxPriorityFeePerGas',
|
|
31
|
+
'eth_getCode',
|
|
32
|
+
'eth_getStorageAt',
|
|
33
|
+
'eth_getLogs',
|
|
34
|
+
'eth_getTransactionCount',
|
|
35
|
+
'net_version',
|
|
36
|
+
'web3_clientVersion',
|
|
37
|
+
'eth_getBlockTransactionCountByNumber',
|
|
38
|
+
'eth_getBlockTransactionCountByHash',
|
|
39
|
+
]);
|
|
40
|
+
// ── RpcPassthrough ────────────────────────────────────────────────
|
|
41
|
+
export class RpcPassthrough {
|
|
42
|
+
rpcPool;
|
|
43
|
+
constructor(rpcPool) {
|
|
44
|
+
this.rpcPool = rpcPool;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Check if a method should be passthrough-proxied.
|
|
48
|
+
*/
|
|
49
|
+
isPassthrough(method) {
|
|
50
|
+
return PASSTHROUGH_METHODS.has(method);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Forward a JSON-RPC request to the upstream RPC endpoint.
|
|
54
|
+
* Preserves the original request id in the response.
|
|
55
|
+
*
|
|
56
|
+
* @param request - The JSON-RPC request to forward
|
|
57
|
+
* @param network - Network slug for RpcPool URL resolution
|
|
58
|
+
* @returns JSON-RPC response (success or error)
|
|
59
|
+
*/
|
|
60
|
+
async forward(request, network) {
|
|
61
|
+
const requestId = request.id ?? null;
|
|
62
|
+
const url = this.rpcPool.getUrl(network);
|
|
63
|
+
try {
|
|
64
|
+
const resp = await fetch(url, {
|
|
65
|
+
method: 'POST',
|
|
66
|
+
headers: { 'Content-Type': 'application/json' },
|
|
67
|
+
body: JSON.stringify({
|
|
68
|
+
jsonrpc: '2.0',
|
|
69
|
+
method: request.method,
|
|
70
|
+
params: request.params ?? [],
|
|
71
|
+
id: request.id ?? 1,
|
|
72
|
+
}),
|
|
73
|
+
});
|
|
74
|
+
if (!resp.ok) {
|
|
75
|
+
return jsonRpcError(requestId, JSON_RPC_ERRORS.SERVER_ERROR, `Upstream RPC error: ${resp.status}`);
|
|
76
|
+
}
|
|
77
|
+
const upstream = (await resp.json());
|
|
78
|
+
// Preserve original request id (upstream may use different id)
|
|
79
|
+
return { ...upstream, jsonrpc: '2.0', id: requestId };
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
return jsonRpcError(requestId, JSON_RPC_ERRORS.SERVER_ERROR, `RPC proxy upstream error: ${err instanceof Error ? err.message : 'unknown'}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=passthrough.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passthrough.js","sourceRoot":"","sources":["../../src/rpc-proxy/passthrough.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EACL,YAAY,EACZ,eAAe,GAGhB,MAAM,eAAe,CAAC;AAEvB,qEAAqE;AAErE;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAS;IACjD,UAAU;IACV,gBAAgB;IAChB,iBAAiB;IACjB,sBAAsB;IACtB,oBAAoB;IACpB,0BAA0B;IAC1B,2BAA2B;IAC3B,iBAAiB;IACjB,cAAc;IACd,gBAAgB;IAChB,0BAA0B;IAC1B,aAAa;IACb,kBAAkB;IAClB,aAAa;IACb,yBAAyB;IACzB,aAAa;IACb,oBAAoB;IACpB,sCAAsC;IACtC,oCAAoC;CACrC,CAAC,CAAC;AAEH,qEAAqE;AAErE,MAAM,OAAO,cAAc;IACL;IAApB,YAAoB,OAAgB;QAAhB,YAAO,GAAP,OAAO,CAAS;IAAG,CAAC;IAExC;;OAEG;IACH,aAAa,CAAC,MAAc;QAC1B,OAAO,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,OAAO,CAAC,OAAuB,EAAE,OAAe;QACpD,MAAM,SAAS,GAAG,OAAO,CAAC,EAAE,IAAI,IAAI,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEzC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAC5B,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,OAAO,EAAE,KAAK;oBACd,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;oBAC5B,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC;iBACpB,CAAC;aACH,CAAC,CAAC;YAEH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACb,OAAO,YAAY,CACjB,SAAS,EACT,eAAe,CAAC,YAAY,EAC5B,uBAAuB,IAAI,CAAC,MAAM,EAAE,CACrC,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAA4B,CAAC;YAChE,+DAA+D;YAC/D,OAAO,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAqB,CAAC;QAC3E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,YAAY,CACjB,SAAS,EACT,eAAe,CAAC,YAAY,EAC5B,6BAA6B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAC9E,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SyncPipelineExecutor -- Synchronous wrapper around the 6-stage pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Converts the existing fire-and-forget pipeline flow into a synchronous
|
|
5
|
+
* request-response model for JSON-RPC. Three paths:
|
|
6
|
+
*
|
|
7
|
+
* 1. INSTANT: stage1-6 run directly, return txHash
|
|
8
|
+
* 2. DELAY: stage1-3.5 run, stage4Wait throws PIPELINE_HALTED,
|
|
9
|
+
* delegate to CompletionWaiter for long-poll
|
|
10
|
+
* 3. APPROVAL: same as DELAY but with longer timeout
|
|
11
|
+
*
|
|
12
|
+
* Anti-Pattern 1: Does NOT modify any existing pipeline code.
|
|
13
|
+
* The PIPELINE_HALTED catch pattern keeps existing flow untouched.
|
|
14
|
+
*
|
|
15
|
+
* @see .planning/research/m31-14-rpc-proxy-ARCHITECTURE.md (Pattern 4)
|
|
16
|
+
*/
|
|
17
|
+
import { type PipelineContext } from '../pipeline/stages.js';
|
|
18
|
+
import type { CompletionWaiter } from './completion-waiter.js';
|
|
19
|
+
import type { SettingsService } from '../infrastructure/settings/settings-service.js';
|
|
20
|
+
export declare class SyncPipelineExecutor {
|
|
21
|
+
private completionWaiter;
|
|
22
|
+
private settingsService?;
|
|
23
|
+
constructor(completionWaiter: CompletionWaiter, settingsService?: SettingsService | undefined);
|
|
24
|
+
/**
|
|
25
|
+
* Execute the 6-stage pipeline synchronously.
|
|
26
|
+
*
|
|
27
|
+
* For INSTANT tier: runs all stages and returns txHash.
|
|
28
|
+
* For DELAY/APPROVAL tier: catches PIPELINE_HALTED and delegates
|
|
29
|
+
* to CompletionWaiter for EventBus-based completion waiting.
|
|
30
|
+
*
|
|
31
|
+
* @param ctx - Pipeline context (same as existing pipeline)
|
|
32
|
+
* @returns Transaction hash
|
|
33
|
+
*/
|
|
34
|
+
execute(ctx: PipelineContext): Promise<string>;
|
|
35
|
+
/**
|
|
36
|
+
* Resolve timeout based on tier and settings.
|
|
37
|
+
*/
|
|
38
|
+
private resolveTimeout;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=sync-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-pipeline.d.ts","sourceRoot":"","sources":["../../src/rpc-proxy/sync-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAQL,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAC;AAItF,qBAAa,oBAAoB;IAE7B,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,eAAe,CAAC;gBADhB,gBAAgB,EAAE,gBAAgB,EAClC,eAAe,CAAC,EAAE,eAAe,YAAA;IAG3C;;;;;;;;;OASG;IACG,OAAO,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IA4BpD;;OAEG;IACH,OAAO,CAAC,cAAc;CASvB"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SyncPipelineExecutor -- Synchronous wrapper around the 6-stage pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Converts the existing fire-and-forget pipeline flow into a synchronous
|
|
5
|
+
* request-response model for JSON-RPC. Three paths:
|
|
6
|
+
*
|
|
7
|
+
* 1. INSTANT: stage1-6 run directly, return txHash
|
|
8
|
+
* 2. DELAY: stage1-3.5 run, stage4Wait throws PIPELINE_HALTED,
|
|
9
|
+
* delegate to CompletionWaiter for long-poll
|
|
10
|
+
* 3. APPROVAL: same as DELAY but with longer timeout
|
|
11
|
+
*
|
|
12
|
+
* Anti-Pattern 1: Does NOT modify any existing pipeline code.
|
|
13
|
+
* The PIPELINE_HALTED catch pattern keeps existing flow untouched.
|
|
14
|
+
*
|
|
15
|
+
* @see .planning/research/m31-14-rpc-proxy-ARCHITECTURE.md (Pattern 4)
|
|
16
|
+
*/
|
|
17
|
+
import { WAIaaSError } from '@waiaas/core';
|
|
18
|
+
import { stage1Validate, stage2Auth, stage3Policy, stage3_5GasCondition, stage4Wait, stage5Execute, stage6Confirm, } from '../pipeline/stages.js';
|
|
19
|
+
// ── SyncPipelineExecutor ──────────────────────────────────────────
|
|
20
|
+
export class SyncPipelineExecutor {
|
|
21
|
+
completionWaiter;
|
|
22
|
+
settingsService;
|
|
23
|
+
constructor(completionWaiter, settingsService) {
|
|
24
|
+
this.completionWaiter = completionWaiter;
|
|
25
|
+
this.settingsService = settingsService;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Execute the 6-stage pipeline synchronously.
|
|
29
|
+
*
|
|
30
|
+
* For INSTANT tier: runs all stages and returns txHash.
|
|
31
|
+
* For DELAY/APPROVAL tier: catches PIPELINE_HALTED and delegates
|
|
32
|
+
* to CompletionWaiter for EventBus-based completion waiting.
|
|
33
|
+
*
|
|
34
|
+
* @param ctx - Pipeline context (same as existing pipeline)
|
|
35
|
+
* @returns Transaction hash
|
|
36
|
+
*/
|
|
37
|
+
async execute(ctx) {
|
|
38
|
+
// Set source for audit trail (SEC-04 preparation for Phase 400)
|
|
39
|
+
ctx.source = 'rpc-proxy';
|
|
40
|
+
// Stages 1-3.5: always run directly
|
|
41
|
+
await stage1Validate(ctx);
|
|
42
|
+
await stage2Auth(ctx);
|
|
43
|
+
await stage3Policy(ctx);
|
|
44
|
+
await stage3_5GasCondition(ctx);
|
|
45
|
+
try {
|
|
46
|
+
await stage4Wait(ctx);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
// DELAY/APPROVAL: stage4Wait throws PIPELINE_HALTED
|
|
50
|
+
if (err instanceof WAIaaSError && err.code === 'PIPELINE_HALTED') {
|
|
51
|
+
const timeoutMs = this.resolveTimeout(ctx.tier);
|
|
52
|
+
return this.completionWaiter.waitForCompletion(ctx.txId, timeoutMs);
|
|
53
|
+
}
|
|
54
|
+
throw err; // Non-HALTED errors propagate
|
|
55
|
+
}
|
|
56
|
+
// INSTANT: stages 5-6 directly
|
|
57
|
+
await stage5Execute(ctx);
|
|
58
|
+
await stage6Confirm(ctx);
|
|
59
|
+
return ctx.submitResult?.txHash ?? '';
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Resolve timeout based on tier and settings.
|
|
63
|
+
*/
|
|
64
|
+
resolveTimeout(tier) {
|
|
65
|
+
if (tier === 'DELAY') {
|
|
66
|
+
const s = this.settingsService?.get('rpc_proxy.delay_timeout_seconds');
|
|
67
|
+
return (s ? parseInt(s, 10) : 300) * 1000;
|
|
68
|
+
}
|
|
69
|
+
// APPROVAL (default)
|
|
70
|
+
const s = this.settingsService?.get('rpc_proxy.approval_timeout_seconds');
|
|
71
|
+
return (s ? parseInt(s, 10) : 600) * 1000;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=sync-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-pipeline.js","sourceRoot":"","sources":["../../src/rpc-proxy/sync-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EACL,cAAc,EACd,UAAU,EACV,YAAY,EACZ,oBAAoB,EACpB,UAAU,EACV,aAAa,EACb,aAAa,GAEd,MAAM,uBAAuB,CAAC;AAI/B,qEAAqE;AAErE,MAAM,OAAO,oBAAoB;IAErB;IACA;IAFV,YACU,gBAAkC,EAClC,eAAiC;QADjC,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,oBAAe,GAAf,eAAe,CAAkB;IACxC,CAAC;IAEJ;;;;;;;;;OASG;IACH,KAAK,CAAC,OAAO,CAAC,GAAoB;QAChC,gEAAgE;QAC/D,GAAW,CAAC,MAAM,GAAG,WAAW,CAAC;QAElC,oCAAoC;QACpC,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;QACtB,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;QACxB,MAAM,oBAAoB,CAAC,GAAG,CAAC,CAAC;QAEhC,IAAI,CAAC;YACH,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,oDAAoD;YACpD,IAAI,GAAG,YAAY,WAAW,IAAI,GAAG,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBACjE,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAChD,OAAO,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YACtE,CAAC;YACD,MAAM,GAAG,CAAC,CAAC,8BAA8B;QAC3C,CAAC;QAED,+BAA+B;QAC/B,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;QACzB,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;QAEzB,OAAO,GAAG,CAAC,YAAY,EAAE,MAAM,IAAI,EAAE,CAAC;IACxC,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,IAAa;QAClC,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,MAAM,CAAC,GAAG,IAAI,CAAC,eAAe,EAAE,GAAG,CAAC,iCAAiC,CAAC,CAAC;YACvE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QAC5C,CAAC;QACD,qBAAqB;QACrB,MAAM,CAAC,GAAG,IAAI,CAAC,eAAe,EAAE,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAC1E,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAC5C,CAAC;CACF"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC Transaction Adapter.
|
|
3
|
+
*
|
|
4
|
+
* Converts eth_sendTransaction params to WAIaaS TransactionRequest format,
|
|
5
|
+
* classifying transactions by type based on the `to` and `data` fields.
|
|
6
|
+
*
|
|
7
|
+
* Classification rules (mirrors tx-parser.ts selectors):
|
|
8
|
+
* - to=null/undefined → CONTRACT_DEPLOY
|
|
9
|
+
* - to + data(0xa9059cbb) → TOKEN_TRANSFER
|
|
10
|
+
* - to + data(0x095ea7b3) → APPROVE
|
|
11
|
+
* - to + data(other) → CONTRACT_CALL
|
|
12
|
+
* - to + no data → TRANSFER
|
|
13
|
+
*
|
|
14
|
+
* Pitfall 14: 0x23b872dd (transferFrom) falls through to CONTRACT_CALL.
|
|
15
|
+
* NFT transfers are NOT classified here.
|
|
16
|
+
*
|
|
17
|
+
* @see .planning/research/m31-14-rpc-proxy-PITFALLS.md (Pitfall 14)
|
|
18
|
+
*/
|
|
19
|
+
export interface EthTransactionParams {
|
|
20
|
+
from?: string;
|
|
21
|
+
to?: string | null;
|
|
22
|
+
value?: string;
|
|
23
|
+
data?: string;
|
|
24
|
+
gas?: string;
|
|
25
|
+
gasPrice?: string;
|
|
26
|
+
maxFeePerGas?: string;
|
|
27
|
+
maxPriorityFeePerGas?: string;
|
|
28
|
+
nonce?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Simplified TransactionRequest output for the RPC proxy layer.
|
|
32
|
+
* These are passed to the 6-stage pipeline which validates via Zod.
|
|
33
|
+
*/
|
|
34
|
+
export type RpcTransactionRequest = {
|
|
35
|
+
type: 'TRANSFER';
|
|
36
|
+
to: string;
|
|
37
|
+
amount: string;
|
|
38
|
+
network: string;
|
|
39
|
+
} | {
|
|
40
|
+
type: 'TOKEN_TRANSFER';
|
|
41
|
+
tokenAddress: string;
|
|
42
|
+
to: string;
|
|
43
|
+
amount: string;
|
|
44
|
+
network: string;
|
|
45
|
+
} | {
|
|
46
|
+
type: 'APPROVE';
|
|
47
|
+
tokenAddress: string;
|
|
48
|
+
spenderAddress: string;
|
|
49
|
+
amount: string;
|
|
50
|
+
network: string;
|
|
51
|
+
} | {
|
|
52
|
+
type: 'CONTRACT_CALL';
|
|
53
|
+
to: string;
|
|
54
|
+
data: string;
|
|
55
|
+
value: string;
|
|
56
|
+
network: string;
|
|
57
|
+
} | {
|
|
58
|
+
type: 'CONTRACT_DEPLOY';
|
|
59
|
+
bytecode: string;
|
|
60
|
+
value: string;
|
|
61
|
+
network: string;
|
|
62
|
+
};
|
|
63
|
+
export declare class RpcTransactionAdapter {
|
|
64
|
+
/**
|
|
65
|
+
* Convert eth_sendTransaction params[0] to WAIaaS TransactionRequest.
|
|
66
|
+
*/
|
|
67
|
+
convert(params: EthTransactionParams, network: string): RpcTransactionRequest;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Convert chain ID number to hex string for eth_chainId responses.
|
|
71
|
+
* e.g., 1 → "0x1", 8453 → "0x2105"
|
|
72
|
+
*/
|
|
73
|
+
export declare function toHexChainId(chainId: number): string;
|
|
74
|
+
/**
|
|
75
|
+
* Convert hex value string to decimal string.
|
|
76
|
+
* Returns '0' if undefined, empty, or '0x'.
|
|
77
|
+
*/
|
|
78
|
+
export declare function hexToDecimal(hex?: string): string;
|
|
79
|
+
//# sourceMappingURL=tx-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tx-adapter.d.ts","sourceRoot":"","sources":["../../src/rpc-proxy/tx-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC7F;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAClG;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACnF;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAIlF,qBAAa,qBAAqB;IAChC;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,GAAG,qBAAqB;CA2D9E;AAID;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAQjD"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC Transaction Adapter.
|
|
3
|
+
*
|
|
4
|
+
* Converts eth_sendTransaction params to WAIaaS TransactionRequest format,
|
|
5
|
+
* classifying transactions by type based on the `to` and `data` fields.
|
|
6
|
+
*
|
|
7
|
+
* Classification rules (mirrors tx-parser.ts selectors):
|
|
8
|
+
* - to=null/undefined → CONTRACT_DEPLOY
|
|
9
|
+
* - to + data(0xa9059cbb) → TOKEN_TRANSFER
|
|
10
|
+
* - to + data(0x095ea7b3) → APPROVE
|
|
11
|
+
* - to + data(other) → CONTRACT_CALL
|
|
12
|
+
* - to + no data → TRANSFER
|
|
13
|
+
*
|
|
14
|
+
* Pitfall 14: 0x23b872dd (transferFrom) falls through to CONTRACT_CALL.
|
|
15
|
+
* NFT transfers are NOT classified here.
|
|
16
|
+
*
|
|
17
|
+
* @see .planning/research/m31-14-rpc-proxy-PITFALLS.md (Pitfall 14)
|
|
18
|
+
*/
|
|
19
|
+
// ── ERC-20 Selectors ──────────────────────────────────────────────
|
|
20
|
+
const ERC20_TRANSFER_SELECTOR = '0xa9059cbb';
|
|
21
|
+
const ERC20_APPROVE_SELECTOR = '0x095ea7b3';
|
|
22
|
+
// ── Adapter ───────────────────────────────────────────────────────
|
|
23
|
+
export class RpcTransactionAdapter {
|
|
24
|
+
/**
|
|
25
|
+
* Convert eth_sendTransaction params[0] to WAIaaS TransactionRequest.
|
|
26
|
+
*/
|
|
27
|
+
convert(params, network) {
|
|
28
|
+
const { to, data, value } = params;
|
|
29
|
+
// CONTRACT_DEPLOY: no `to` field
|
|
30
|
+
if (to === null || to === undefined) {
|
|
31
|
+
return {
|
|
32
|
+
type: 'CONTRACT_DEPLOY',
|
|
33
|
+
bytecode: data ?? '0x',
|
|
34
|
+
value: hexToDecimal(value),
|
|
35
|
+
network,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// Has data? Classify by selector
|
|
39
|
+
if (data && data !== '0x' && data.length >= 10) {
|
|
40
|
+
const selector = data.slice(0, 10).toLowerCase();
|
|
41
|
+
// ERC-20 transfer(address,uint256)
|
|
42
|
+
if (selector === ERC20_TRANSFER_SELECTOR) {
|
|
43
|
+
const { address: recipient, amount } = decodeAddressAndUint256(data);
|
|
44
|
+
return {
|
|
45
|
+
type: 'TOKEN_TRANSFER',
|
|
46
|
+
tokenAddress: to,
|
|
47
|
+
to: recipient,
|
|
48
|
+
amount,
|
|
49
|
+
network,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// ERC-20 approve(address,uint256)
|
|
53
|
+
if (selector === ERC20_APPROVE_SELECTOR) {
|
|
54
|
+
const { address: spender, amount } = decodeAddressAndUint256(data);
|
|
55
|
+
return {
|
|
56
|
+
type: 'APPROVE',
|
|
57
|
+
tokenAddress: to,
|
|
58
|
+
spenderAddress: spender,
|
|
59
|
+
amount,
|
|
60
|
+
network,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Other contract call (including transferFrom 0x23b872dd → Pitfall 14)
|
|
64
|
+
return {
|
|
65
|
+
type: 'CONTRACT_CALL',
|
|
66
|
+
to,
|
|
67
|
+
data,
|
|
68
|
+
value: hexToDecimal(value),
|
|
69
|
+
network,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Native TRANSFER: to + no data (or empty data)
|
|
73
|
+
return {
|
|
74
|
+
type: 'TRANSFER',
|
|
75
|
+
to,
|
|
76
|
+
amount: hexToDecimal(value),
|
|
77
|
+
network,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// ── Utility Functions ─────────────────────────────────────────────
|
|
82
|
+
/**
|
|
83
|
+
* Convert chain ID number to hex string for eth_chainId responses.
|
|
84
|
+
* e.g., 1 → "0x1", 8453 → "0x2105"
|
|
85
|
+
*/
|
|
86
|
+
export function toHexChainId(chainId) {
|
|
87
|
+
return '0x' + chainId.toString(16);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Convert hex value string to decimal string.
|
|
91
|
+
* Returns '0' if undefined, empty, or '0x'.
|
|
92
|
+
*/
|
|
93
|
+
export function hexToDecimal(hex) {
|
|
94
|
+
if (!hex || hex === '0x' || hex === '0x0') {
|
|
95
|
+
return '0';
|
|
96
|
+
}
|
|
97
|
+
// Remove 0x prefix and parse as BigInt for large values
|
|
98
|
+
const cleaned = hex.startsWith('0x') ? hex.slice(2) : hex;
|
|
99
|
+
if (!cleaned)
|
|
100
|
+
return '0';
|
|
101
|
+
return BigInt('0x' + cleaned).toString(10);
|
|
102
|
+
}
|
|
103
|
+
// ── Internal Helpers ──────────────────────────────────────────────
|
|
104
|
+
/**
|
|
105
|
+
* Decode ABI-encoded (address, uint256) from calldata after the 4-byte selector.
|
|
106
|
+
* Used for ERC-20 transfer(address,uint256) and approve(address,uint256).
|
|
107
|
+
*/
|
|
108
|
+
function decodeAddressAndUint256(data) {
|
|
109
|
+
// data format: 0x{selector:8}{address:64}{uint256:64}
|
|
110
|
+
// Address is bytes 10-74 (last 40 chars of 64-char padded address)
|
|
111
|
+
const addressHex = data.slice(34, 74); // skip 0x + 8 selector + 24 padding
|
|
112
|
+
const amountHex = data.slice(74, 138);
|
|
113
|
+
const address = '0x' + addressHex.toLowerCase();
|
|
114
|
+
const amount = amountHex ? BigInt('0x' + amountHex).toString(10) : '0';
|
|
115
|
+
return { address, amount };
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=tx-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tx-adapter.js","sourceRoot":"","sources":["../../src/rpc-proxy/tx-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"async-polling-service.d.ts","sourceRoot":"","sources":["../../src/services/async-polling-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,KAAK,MAAM,MAAM,sCAAsC,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAqC,MAAM,iBAAiB,CAAC;AAI9F,4BAA4B;AAC5B,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wEAAwE;AACxE,MAAM,WAAW,qBAAqB;IACpC,iCAAiC;IACjC,gBAAgB,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5F,4DAA4D;IAC5D,kBAAkB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,wFAAwF;IACxF,cAAc,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACvD;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAI5B,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAJ7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+C;gBAGrD,EAAE,EAAE,qBAAqB,CAAC,OAAO,MAAM,CAAC,EACxC,SAAS,CAAC,EAAE,qBAAqB,YAAA;IAGpD;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAInD,mDAAmD;IACnD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;;;;;OAMG;IACG,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAwEpC;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;
|
|
1
|
+
{"version":3,"file":"async-polling-service.d.ts","sourceRoot":"","sources":["../../src/services/async-polling-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,KAAK,MAAM,MAAM,sCAAsC,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAqC,MAAM,iBAAiB,CAAC;AAI9F,4BAA4B;AAC5B,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wEAAwE;AACxE,MAAM,WAAW,qBAAqB;IACpC,iCAAiC;IACjC,gBAAgB,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5F,4DAA4D;IAC5D,kBAAkB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,wFAAwF;IACxF,cAAc,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACvD;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAI5B,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAJ7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+C;gBAGrD,EAAE,EAAE,qBAAqB,CAAC,OAAO,MAAM,CAAC,EACxC,SAAS,CAAC,EAAE,qBAAqB,YAAA;IAGpD;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAInD,mDAAmD;IACnD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;;;;;OAMG;IACG,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAwEpC;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;;;;;OAMG;YACW,aAAa;IAiF3B;;;;;;;OAOG;YACW,aAAa;CAqN5B"}
|