tempo.ts 0.7.1 → 0.7.3
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/CHANGELOG.md +38 -0
- package/dist/server/Handler.d.ts +12 -2
- package/dist/server/Handler.d.ts.map +1 -1
- package/dist/server/Handler.js +71 -44
- package/dist/server/Handler.js.map +1 -1
- package/package.json +1 -1
- package/src/server/Handler.test.ts +248 -0
- package/src/server/Handler.ts +112 -60
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# tempo.ts
|
|
2
2
|
|
|
3
|
+
## 0.7.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`f0369cd`](https://github.com/tempoxyz/tempo-ts/commit/f0369cd13c6d651c2aff1abe85e7984a60588f0f) Thanks [@jxom](https://github.com/jxom)! - Added error handling to `Handler.feePayer`.
|
|
8
|
+
|
|
9
|
+
## 0.7.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#90](https://github.com/tempoxyz/tempo-ts/pull/90) [`625c8e4`](https://github.com/tempoxyz/tempo-ts/commit/625c8e4a4b0c4fac3d6c278c9a964fc5d6b7a78f) Thanks [@jxom](https://github.com/jxom)! - Added `Handler.compose` to compose multiple handlers into a single handler.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { Handler, Kv } from 'tempo.ts/server'
|
|
17
|
+
|
|
18
|
+
const handler = Handler.compose([
|
|
19
|
+
Handler.feePayer({
|
|
20
|
+
account,
|
|
21
|
+
client,
|
|
22
|
+
path: '/fee-payer'
|
|
23
|
+
}),
|
|
24
|
+
Handler.keyManager({
|
|
25
|
+
kv: Kv.memory()
|
|
26
|
+
path: '/key'
|
|
27
|
+
}),
|
|
28
|
+
], { path: '/api' })
|
|
29
|
+
|
|
30
|
+
Bun.serve(handler) // Bun
|
|
31
|
+
Deno.serve(handler) // Deno
|
|
32
|
+
createServer(handler.listener) // Node.js
|
|
33
|
+
app.use(c => handler.fetch(c.req.raw)) // Hono
|
|
34
|
+
app.use(handler.listener) // Express
|
|
35
|
+
|
|
36
|
+
// Exposed endpoints:
|
|
37
|
+
// - '/api/fee-payer'
|
|
38
|
+
// - '/api/key/*'
|
|
39
|
+
```
|
|
40
|
+
|
|
3
41
|
## 0.7.1
|
|
4
42
|
|
|
5
43
|
### Patch Changes
|
package/dist/server/Handler.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Router } from '@remix-run/fetch-router';
|
|
1
|
+
import { type Router, type RouterOptions } from '@remix-run/fetch-router';
|
|
2
2
|
import { RpcRequest } from 'ox';
|
|
3
3
|
import * as Hex from 'ox/Hex';
|
|
4
4
|
import type * as WebAuthnP256 from 'ox/WebAuthnP256';
|
|
@@ -9,13 +9,23 @@ import type * as Kv from './Kv.js';
|
|
|
9
9
|
export type Handler = Router & {
|
|
10
10
|
listener: (req: any, res: any) => void;
|
|
11
11
|
};
|
|
12
|
+
export declare function compose(handlers: Handler[], options?: compose.Options): Handler;
|
|
13
|
+
export declare namespace compose {
|
|
14
|
+
type Options = {
|
|
15
|
+
/** The path to use for the handler. */
|
|
16
|
+
path?: string | undefined;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
12
19
|
/**
|
|
13
20
|
* Instantiates a new request handler.
|
|
14
21
|
*
|
|
15
22
|
* @param options - constructor options
|
|
16
23
|
* @returns Handler instance
|
|
17
24
|
*/
|
|
18
|
-
export declare function from(): Handler;
|
|
25
|
+
export declare function from(options?: from.Options): Handler;
|
|
26
|
+
export declare namespace from {
|
|
27
|
+
type Options = RouterOptions;
|
|
28
|
+
}
|
|
19
29
|
/**
|
|
20
30
|
* Defines a Key Manager request handler.
|
|
21
31
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Handler.d.ts","sourceRoot":"","sources":["../../src/server/Handler.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Handler.d.ts","sourceRoot":"","sources":["../../src/server/Handler.ts"],"names":[],"mappings":"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"}
|
package/dist/server/Handler.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createRouter } from '@remix-run/fetch-router';
|
|
1
|
+
import { createRouter, } from '@remix-run/fetch-router';
|
|
2
2
|
import { RpcRequest, RpcResponse } from 'ox';
|
|
3
3
|
import * as Base64 from 'ox/Base64';
|
|
4
4
|
import * as Hex from 'ox/Hex';
|
|
@@ -7,14 +7,32 @@ import { signTransaction } from 'viem/actions';
|
|
|
7
7
|
import { formatTransaction } from '../viem/Formatters.js';
|
|
8
8
|
import * as Transaction from '../viem/Transaction.js';
|
|
9
9
|
import * as RequestListener from './internal/requestListener.js';
|
|
10
|
+
export function compose(handlers, options = {}) {
|
|
11
|
+
const path = options.path ?? '/';
|
|
12
|
+
return from({
|
|
13
|
+
async defaultHandler(context) {
|
|
14
|
+
const url = new URL(context.request.url);
|
|
15
|
+
if (!url.pathname.startsWith(path))
|
|
16
|
+
return new Response('Not Found', { status: 404 });
|
|
17
|
+
url.pathname = url.pathname.replace(path, '');
|
|
18
|
+
for (const handler of handlers) {
|
|
19
|
+
const request = new Request(url, context.request.clone());
|
|
20
|
+
const response = await handler.fetch(request);
|
|
21
|
+
if (response.status !== 404)
|
|
22
|
+
return response;
|
|
23
|
+
}
|
|
24
|
+
return new Response('Not Found', { status: 404 });
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
10
28
|
/**
|
|
11
29
|
* Instantiates a new request handler.
|
|
12
30
|
*
|
|
13
31
|
* @param options - constructor options
|
|
14
32
|
* @returns Handler instance
|
|
15
33
|
*/
|
|
16
|
-
export function from() {
|
|
17
|
-
const router = createRouter();
|
|
34
|
+
export function from(options = {}) {
|
|
35
|
+
const router = createRouter(options);
|
|
18
36
|
return {
|
|
19
37
|
...router,
|
|
20
38
|
listener: RequestListener.fromFetchHandler((request) => {
|
|
@@ -392,49 +410,58 @@ export function feePayer(options) {
|
|
|
392
410
|
const router = from();
|
|
393
411
|
router.post(path, async ({ request: req }) => {
|
|
394
412
|
const request = RpcRequest.from((await req.json()));
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
413
|
+
try {
|
|
414
|
+
await onRequest?.(request);
|
|
415
|
+
if (request.method === 'eth_signTransaction') {
|
|
416
|
+
const transactionRequest = formatTransaction(request.params?.[0]);
|
|
417
|
+
const serializedTransaction = await signTransaction(client, {
|
|
418
|
+
...transactionRequest,
|
|
419
|
+
account,
|
|
420
|
+
// @ts-expect-error
|
|
421
|
+
feePayer: account,
|
|
422
|
+
});
|
|
423
|
+
return Response.json(RpcResponse.from({ result: serializedTransaction }, { request }));
|
|
424
|
+
}
|
|
425
|
+
if (request.method === 'eth_signRawTransaction') {
|
|
426
|
+
const serialized = request.params?.[0];
|
|
427
|
+
const transaction = Transaction.deserialize(serialized);
|
|
428
|
+
const serializedTransaction = await signTransaction(client, {
|
|
429
|
+
...transaction,
|
|
430
|
+
account,
|
|
431
|
+
// @ts-expect-error
|
|
432
|
+
feePayer: account,
|
|
433
|
+
});
|
|
434
|
+
return Response.json(RpcResponse.from({ result: serializedTransaction }, { request }));
|
|
435
|
+
}
|
|
436
|
+
if (request.method === 'eth_sendRawTransaction' ||
|
|
437
|
+
request.method === 'eth_sendRawTransactionSync') {
|
|
438
|
+
const serialized = request.params?.[0];
|
|
439
|
+
const transaction = Transaction.deserialize(serialized);
|
|
440
|
+
const serializedTransaction = await signTransaction(client, {
|
|
441
|
+
...transaction,
|
|
442
|
+
account,
|
|
443
|
+
// @ts-expect-error
|
|
444
|
+
feePayer: account,
|
|
445
|
+
});
|
|
446
|
+
const result = await client.request({
|
|
447
|
+
method: request.method,
|
|
448
|
+
params: [serializedTransaction],
|
|
449
|
+
});
|
|
450
|
+
return Response.json(RpcResponse.from({ result }, { request }));
|
|
451
|
+
}
|
|
452
|
+
return Response.json(RpcResponse.from({
|
|
453
|
+
error: new RpcResponse.MethodNotSupportedError({
|
|
454
|
+
message: `Method not supported: ${request.method}`,
|
|
455
|
+
}),
|
|
456
|
+
}, { request }));
|
|
405
457
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
// @ts-expect-error
|
|
413
|
-
feePayer: account,
|
|
414
|
-
});
|
|
415
|
-
return Response.json(RpcResponse.from({ result: serializedTransaction }, { request }));
|
|
416
|
-
}
|
|
417
|
-
if (request.method === 'eth_sendRawTransaction' ||
|
|
418
|
-
request.method === 'eth_sendRawTransactionSync') {
|
|
419
|
-
const serialized = request.params?.[0];
|
|
420
|
-
const transaction = Transaction.deserialize(serialized);
|
|
421
|
-
const serializedTransaction = await signTransaction(client, {
|
|
422
|
-
...transaction,
|
|
423
|
-
account,
|
|
424
|
-
// @ts-expect-error
|
|
425
|
-
feePayer: account,
|
|
426
|
-
});
|
|
427
|
-
const result = await client.request({
|
|
428
|
-
method: request.method,
|
|
429
|
-
params: [serializedTransaction],
|
|
430
|
-
});
|
|
431
|
-
return Response.json(RpcResponse.from({ result }, { request }));
|
|
458
|
+
catch (error) {
|
|
459
|
+
return Response.json(RpcResponse.from({
|
|
460
|
+
error: new RpcResponse.InternalError({
|
|
461
|
+
message: error.message,
|
|
462
|
+
}),
|
|
463
|
+
}, { request }));
|
|
432
464
|
}
|
|
433
|
-
return Response.json(RpcResponse.from({
|
|
434
|
-
error: new RpcResponse.MethodNotSupportedError({
|
|
435
|
-
message: `Method not supported: ${request.method}`,
|
|
436
|
-
}),
|
|
437
|
-
}, { request }), { status: 400 });
|
|
438
465
|
});
|
|
439
466
|
return router;
|
|
440
467
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Handler.js","sourceRoot":"","sources":["../../src/server/Handler.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Handler.js","sourceRoot":"","sources":["../../src/server/Handler.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Elysia } from 'elysia'
|
|
1
2
|
import express from 'express'
|
|
2
3
|
import { Hono } from 'hono'
|
|
3
4
|
import type { RpcRequest } from 'ox'
|
|
@@ -20,6 +21,210 @@ import { withFeePayer } from '../viem/Transport.js'
|
|
|
20
21
|
import * as Handler from './Handler.js'
|
|
21
22
|
import * as Kv from './Kv.js'
|
|
22
23
|
|
|
24
|
+
describe('compose', () => {
|
|
25
|
+
test('default', async () => {
|
|
26
|
+
const handler1 = Handler.from()
|
|
27
|
+
handler1.get('/test', () => new Response('test'))
|
|
28
|
+
const handler2 = Handler.from()
|
|
29
|
+
handler2.get('/test2', () => new Response('test2'))
|
|
30
|
+
|
|
31
|
+
const handler = Handler.compose([handler1, handler2])
|
|
32
|
+
expect(handler).toBeDefined()
|
|
33
|
+
|
|
34
|
+
{
|
|
35
|
+
const response = await handler.fetch(new Request('http://localhost/test'))
|
|
36
|
+
expect(response.status).toBe(200)
|
|
37
|
+
expect(await response.text()).toBe('test')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
const response = await handler.fetch(
|
|
42
|
+
new Request('http://localhost/test2'),
|
|
43
|
+
)
|
|
44
|
+
expect(response.status).toBe(200)
|
|
45
|
+
expect(await response.text()).toBe('test2')
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('behavior: path', async () => {
|
|
50
|
+
const handler1 = Handler.from()
|
|
51
|
+
handler1.get('/test', () => new Response('test'))
|
|
52
|
+
const handler2 = Handler.from()
|
|
53
|
+
handler2.get('/test2', () => new Response('test2'))
|
|
54
|
+
|
|
55
|
+
const handler = Handler.compose([handler1, handler2], {
|
|
56
|
+
path: '/api',
|
|
57
|
+
})
|
|
58
|
+
expect(handler).toBeDefined()
|
|
59
|
+
|
|
60
|
+
{
|
|
61
|
+
const response = await handler.fetch(
|
|
62
|
+
new Request('http://localhost/api/test'),
|
|
63
|
+
)
|
|
64
|
+
expect(response.status).toBe(200)
|
|
65
|
+
expect(await response.text()).toBe('test')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
{
|
|
69
|
+
const response = await handler.fetch(
|
|
70
|
+
new Request('http://localhost/api/test2'),
|
|
71
|
+
)
|
|
72
|
+
expect(response.status).toBe(200)
|
|
73
|
+
expect(await response.text()).toBe('test2')
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
describe('integration', () => {
|
|
78
|
+
const handler1 = Handler.from()
|
|
79
|
+
handler1.get('/foo', () => new Response('foo'))
|
|
80
|
+
handler1.post('/bar', () => new Response('bar'))
|
|
81
|
+
|
|
82
|
+
const handler2 = Handler.from()
|
|
83
|
+
handler2.get('/baz', () => new Response('baz'))
|
|
84
|
+
handler2.post('/qux', () => new Response('qux'))
|
|
85
|
+
|
|
86
|
+
const handler = Handler.compose([handler1, handler2], {
|
|
87
|
+
path: '/api',
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
test('hono', async () => {
|
|
91
|
+
const app = new Hono()
|
|
92
|
+
app.use((c) => handler.fetch(c.req.raw))
|
|
93
|
+
|
|
94
|
+
{
|
|
95
|
+
const response = await app.request('/api/foo')
|
|
96
|
+
expect(await response.text()).toBe('foo')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
{
|
|
100
|
+
const response = await app.request('/api/bar', {
|
|
101
|
+
method: 'POST',
|
|
102
|
+
})
|
|
103
|
+
expect(await response.text()).toBe('bar')
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
{
|
|
107
|
+
const response = await app.request('/api/baz', {
|
|
108
|
+
method: 'GET',
|
|
109
|
+
})
|
|
110
|
+
expect(await response.text()).toBe('baz')
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
const response = await app.request('/api/qux', {
|
|
115
|
+
method: 'POST',
|
|
116
|
+
})
|
|
117
|
+
expect(await response.text()).toBe('qux')
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
test('elysia', async () => {
|
|
122
|
+
const app = new Elysia().all('*', ({ request }) => handler.fetch(request))
|
|
123
|
+
|
|
124
|
+
{
|
|
125
|
+
const response = await app.handle(
|
|
126
|
+
new Request('http://localhost/api/foo'),
|
|
127
|
+
)
|
|
128
|
+
expect(await response.text()).toBe('foo')
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
{
|
|
132
|
+
const response = await app.handle(
|
|
133
|
+
new Request('http://localhost/api/bar', {
|
|
134
|
+
method: 'POST',
|
|
135
|
+
}),
|
|
136
|
+
)
|
|
137
|
+
expect(await response.text()).toBe('bar')
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
{
|
|
141
|
+
const response = await app.handle(
|
|
142
|
+
new Request('http://localhost/api/baz', {
|
|
143
|
+
method: 'GET',
|
|
144
|
+
}),
|
|
145
|
+
)
|
|
146
|
+
expect(await response.text()).toBe('baz')
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
{
|
|
150
|
+
const response = await app.handle(
|
|
151
|
+
new Request('http://localhost/api/qux', {
|
|
152
|
+
method: 'POST',
|
|
153
|
+
}),
|
|
154
|
+
)
|
|
155
|
+
expect(await response.text()).toBe('qux')
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
test('node.js', async () => {
|
|
160
|
+
const server = await createServer(handler.listener)
|
|
161
|
+
|
|
162
|
+
{
|
|
163
|
+
const response = await fetch(`${server.url}/api/foo`)
|
|
164
|
+
expect(await response.text()).toBe('foo')
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
{
|
|
168
|
+
const response = await fetch(`${server.url}/api/bar`, {
|
|
169
|
+
method: 'POST',
|
|
170
|
+
})
|
|
171
|
+
expect(await response.text()).toBe('bar')
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
{
|
|
175
|
+
const response = await fetch(`${server.url}/api/baz`, {
|
|
176
|
+
method: 'GET',
|
|
177
|
+
})
|
|
178
|
+
expect(await response.text()).toBe('baz')
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
{
|
|
182
|
+
const response = await fetch(`${server.url}/api/qux`, {
|
|
183
|
+
method: 'POST',
|
|
184
|
+
})
|
|
185
|
+
expect(await response.text()).toBe('qux')
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
await server.closeAsync()
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
test('express', async () => {
|
|
192
|
+
const app = express()
|
|
193
|
+
app.use(handler.listener)
|
|
194
|
+
|
|
195
|
+
const server = await createServer(app)
|
|
196
|
+
|
|
197
|
+
{
|
|
198
|
+
const response = await fetch(`${server.url}/api/foo`)
|
|
199
|
+
expect(await response.text()).toBe('foo')
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
{
|
|
203
|
+
const response = await fetch(`${server.url}/api/bar`, {
|
|
204
|
+
method: 'POST',
|
|
205
|
+
})
|
|
206
|
+
expect(await response.text()).toBe('bar')
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
{
|
|
210
|
+
const response = await fetch(`${server.url}/api/baz`, {
|
|
211
|
+
method: 'GET',
|
|
212
|
+
})
|
|
213
|
+
expect(await response.text()).toBe('baz')
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
{
|
|
217
|
+
const response = await fetch(`${server.url}/api/qux`, {
|
|
218
|
+
method: 'POST',
|
|
219
|
+
})
|
|
220
|
+
expect(await response.text()).toBe('qux')
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
await server.closeAsync()
|
|
224
|
+
})
|
|
225
|
+
})
|
|
226
|
+
})
|
|
227
|
+
|
|
23
228
|
describe('from', () => {
|
|
24
229
|
test('default', () => {
|
|
25
230
|
const handler = Handler.from()
|
|
@@ -73,6 +278,24 @@ describe('from', () => {
|
|
|
73
278
|
}
|
|
74
279
|
})
|
|
75
280
|
|
|
281
|
+
test('elysia', async () => {
|
|
282
|
+
const app = new Elysia().all('*', ({ request }) => handler.fetch(request))
|
|
283
|
+
|
|
284
|
+
{
|
|
285
|
+
const response = await app.handle(new Request('http://localhost/foo'))
|
|
286
|
+
expect(await response.text()).toBe('foo')
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
{
|
|
290
|
+
const response = await app.handle(
|
|
291
|
+
new Request('http://localhost/bar', {
|
|
292
|
+
method: 'POST',
|
|
293
|
+
}),
|
|
294
|
+
)
|
|
295
|
+
expect(await response.text()).toBe('bar')
|
|
296
|
+
}
|
|
297
|
+
})
|
|
298
|
+
|
|
76
299
|
test('node.js', async () => {
|
|
77
300
|
const server = await createServer(handler.listener)
|
|
78
301
|
|
|
@@ -562,5 +785,30 @@ describe('feePayer', () => {
|
|
|
562
785
|
}
|
|
563
786
|
`)
|
|
564
787
|
})
|
|
788
|
+
|
|
789
|
+
test('behavior: internal error', async () => {
|
|
790
|
+
const response = await fetch(server.url, {
|
|
791
|
+
method: 'POST',
|
|
792
|
+
body: JSON.stringify({
|
|
793
|
+
jsonrpc: '2.0',
|
|
794
|
+
id: 1,
|
|
795
|
+
method: 'eth_signRawTransaction',
|
|
796
|
+
params: ['0xinvalid'],
|
|
797
|
+
}),
|
|
798
|
+
})
|
|
799
|
+
|
|
800
|
+
const data = await response.json()
|
|
801
|
+
expect(data).toMatchInlineSnapshot(`
|
|
802
|
+
{
|
|
803
|
+
"error": {
|
|
804
|
+
"code": -32603,
|
|
805
|
+
"name": "RpcResponse.InternalError",
|
|
806
|
+
"stack": "",
|
|
807
|
+
},
|
|
808
|
+
"id": 1,
|
|
809
|
+
"jsonrpc": "2.0",
|
|
810
|
+
}
|
|
811
|
+
`)
|
|
812
|
+
})
|
|
565
813
|
})
|
|
566
814
|
})
|
package/src/server/Handler.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createRouter,
|
|
3
|
+
type Router,
|
|
4
|
+
type RouterOptions,
|
|
5
|
+
} from '@remix-run/fetch-router'
|
|
2
6
|
import { RpcRequest, RpcResponse } from 'ox'
|
|
3
7
|
import * as Base64 from 'ox/Base64'
|
|
4
8
|
import * as Hex from 'ox/Hex'
|
|
@@ -16,14 +20,44 @@ export type Handler = Router & {
|
|
|
16
20
|
listener: (req: any, res: any) => void
|
|
17
21
|
}
|
|
18
22
|
|
|
23
|
+
export function compose(
|
|
24
|
+
handlers: Handler[],
|
|
25
|
+
options: compose.Options = {},
|
|
26
|
+
): Handler {
|
|
27
|
+
const path = options.path ?? '/'
|
|
28
|
+
|
|
29
|
+
return from({
|
|
30
|
+
async defaultHandler(context) {
|
|
31
|
+
const url = new URL(context.request.url)
|
|
32
|
+
if (!url.pathname.startsWith(path))
|
|
33
|
+
return new Response('Not Found', { status: 404 })
|
|
34
|
+
|
|
35
|
+
url.pathname = url.pathname.replace(path, '')
|
|
36
|
+
for (const handler of handlers) {
|
|
37
|
+
const request = new Request(url, context.request.clone())
|
|
38
|
+
const response = await handler.fetch(request)
|
|
39
|
+
if (response.status !== 404) return response
|
|
40
|
+
}
|
|
41
|
+
return new Response('Not Found', { status: 404 })
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export declare namespace compose {
|
|
47
|
+
export type Options = {
|
|
48
|
+
/** The path to use for the handler. */
|
|
49
|
+
path?: string | undefined
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
19
53
|
/**
|
|
20
54
|
* Instantiates a new request handler.
|
|
21
55
|
*
|
|
22
56
|
* @param options - constructor options
|
|
23
57
|
* @returns Handler instance
|
|
24
58
|
*/
|
|
25
|
-
export function from(): Handler {
|
|
26
|
-
const router = createRouter()
|
|
59
|
+
export function from(options: from.Options = {}): Handler {
|
|
60
|
+
const router = createRouter(options)
|
|
27
61
|
return {
|
|
28
62
|
...router,
|
|
29
63
|
listener: RequestListener.fromFetchHandler((request) => {
|
|
@@ -32,6 +66,10 @@ export function from(): Handler {
|
|
|
32
66
|
}
|
|
33
67
|
}
|
|
34
68
|
|
|
69
|
+
export declare namespace from {
|
|
70
|
+
export type Options = RouterOptions
|
|
71
|
+
}
|
|
72
|
+
|
|
35
73
|
/**
|
|
36
74
|
* Defines a Key Manager request handler.
|
|
37
75
|
*
|
|
@@ -483,72 +521,86 @@ export function feePayer(options: feePayer.Options) {
|
|
|
483
521
|
router.post(path, async ({ request: req }) => {
|
|
484
522
|
const request = RpcRequest.from((await req.json()) as any)
|
|
485
523
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
if (request.method === 'eth_signTransaction') {
|
|
489
|
-
const transactionRequest = formatTransaction(request.params?.[0] as never)
|
|
524
|
+
try {
|
|
525
|
+
await onRequest?.(request)
|
|
490
526
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
feePayer: account,
|
|
496
|
-
})
|
|
527
|
+
if (request.method === 'eth_signTransaction') {
|
|
528
|
+
const transactionRequest = formatTransaction(
|
|
529
|
+
request.params?.[0] as never,
|
|
530
|
+
)
|
|
497
531
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
532
|
+
const serializedTransaction = await signTransaction(client, {
|
|
533
|
+
...transactionRequest,
|
|
534
|
+
account,
|
|
535
|
+
// @ts-expect-error
|
|
536
|
+
feePayer: account,
|
|
537
|
+
})
|
|
502
538
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
539
|
+
return Response.json(
|
|
540
|
+
RpcResponse.from({ result: serializedTransaction }, { request }),
|
|
541
|
+
)
|
|
542
|
+
}
|
|
506
543
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
// @ts-expect-error
|
|
511
|
-
feePayer: account,
|
|
512
|
-
})
|
|
544
|
+
if ((request as any).method === 'eth_signRawTransaction') {
|
|
545
|
+
const serialized = request.params?.[0] as `0x76${string}`
|
|
546
|
+
const transaction = Transaction.deserialize(serialized)
|
|
513
547
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
548
|
+
const serializedTransaction = await signTransaction(client, {
|
|
549
|
+
...transaction,
|
|
550
|
+
account,
|
|
551
|
+
// @ts-expect-error
|
|
552
|
+
feePayer: account,
|
|
553
|
+
})
|
|
518
554
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
const serialized = request.params?.[0] as `0x76${string}`
|
|
524
|
-
const transaction = Transaction.deserialize(serialized)
|
|
525
|
-
|
|
526
|
-
const serializedTransaction = await signTransaction(client, {
|
|
527
|
-
...transaction,
|
|
528
|
-
account,
|
|
529
|
-
// @ts-expect-error
|
|
530
|
-
feePayer: account,
|
|
531
|
-
})
|
|
555
|
+
return Response.json(
|
|
556
|
+
RpcResponse.from({ result: serializedTransaction }, { request }),
|
|
557
|
+
)
|
|
558
|
+
}
|
|
532
559
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
560
|
+
if (
|
|
561
|
+
request.method === 'eth_sendRawTransaction' ||
|
|
562
|
+
request.method === 'eth_sendRawTransactionSync'
|
|
563
|
+
) {
|
|
564
|
+
const serialized = request.params?.[0] as `0x76${string}`
|
|
565
|
+
const transaction = Transaction.deserialize(serialized)
|
|
566
|
+
|
|
567
|
+
const serializedTransaction = await signTransaction(client, {
|
|
568
|
+
...transaction,
|
|
569
|
+
account,
|
|
570
|
+
// @ts-expect-error
|
|
571
|
+
feePayer: account,
|
|
572
|
+
})
|
|
573
|
+
|
|
574
|
+
const result = await client.request({
|
|
575
|
+
method: request.method,
|
|
576
|
+
params: [serializedTransaction],
|
|
577
|
+
})
|
|
578
|
+
|
|
579
|
+
return Response.json(RpcResponse.from({ result }, { request }))
|
|
580
|
+
}
|
|
537
581
|
|
|
538
|
-
return Response.json(
|
|
582
|
+
return Response.json(
|
|
583
|
+
RpcResponse.from(
|
|
584
|
+
{
|
|
585
|
+
error: new RpcResponse.MethodNotSupportedError({
|
|
586
|
+
message: `Method not supported: ${request.method}`,
|
|
587
|
+
}),
|
|
588
|
+
},
|
|
589
|
+
{ request },
|
|
590
|
+
),
|
|
591
|
+
)
|
|
592
|
+
} catch (error) {
|
|
593
|
+
return Response.json(
|
|
594
|
+
RpcResponse.from(
|
|
595
|
+
{
|
|
596
|
+
error: new RpcResponse.InternalError({
|
|
597
|
+
message: (error as Error).message,
|
|
598
|
+
}),
|
|
599
|
+
},
|
|
600
|
+
{ request },
|
|
601
|
+
),
|
|
602
|
+
)
|
|
539
603
|
}
|
|
540
|
-
|
|
541
|
-
return Response.json(
|
|
542
|
-
RpcResponse.from(
|
|
543
|
-
{
|
|
544
|
-
error: new RpcResponse.MethodNotSupportedError({
|
|
545
|
-
message: `Method not supported: ${request.method}`,
|
|
546
|
-
}),
|
|
547
|
-
},
|
|
548
|
-
{ request },
|
|
549
|
-
),
|
|
550
|
-
{ status: 400 },
|
|
551
|
-
)
|
|
552
604
|
})
|
|
553
605
|
|
|
554
606
|
return router
|