accounts 0.6.1 → 0.6.2
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 +8 -0
- package/dist/core/Schema.d.ts +12 -12
- package/dist/core/adapters/dialog.d.ts.map +1 -1
- package/dist/core/adapters/dialog.js +3 -1
- package/dist/core/adapters/dialog.js.map +1 -1
- package/dist/core/zod/rpc.d.ts +9 -9
- package/dist/core/zod/rpc.js +1 -1
- package/dist/core/zod/rpc.js.map +1 -1
- package/dist/server/CliAuth.d.ts +11 -11
- package/dist/server/CliAuth.js +1 -1
- package/dist/server/CliAuth.js.map +1 -1
- package/dist/server/Handler.d.ts +4 -252
- package/dist/server/Handler.d.ts.map +1 -1
- package/dist/server/Handler.js +4 -573
- package/dist/server/Handler.js.map +1 -1
- package/dist/server/internal/handlers/codeAuth.d.ts +41 -0
- package/dist/server/internal/handlers/codeAuth.d.ts.map +1 -0
- package/dist/server/internal/handlers/codeAuth.js +104 -0
- package/dist/server/internal/handlers/codeAuth.js.map +1 -0
- package/dist/server/internal/handlers/feePayer.d.ts +73 -0
- package/dist/server/internal/handlers/feePayer.d.ts.map +1 -0
- package/dist/server/internal/handlers/feePayer.js +184 -0
- package/dist/server/internal/handlers/feePayer.js.map +1 -0
- package/dist/server/internal/handlers/relay.d.ts +148 -0
- package/dist/server/internal/handlers/relay.d.ts.map +1 -0
- package/dist/server/internal/handlers/relay.js +600 -0
- package/dist/server/internal/handlers/relay.js.map +1 -0
- package/dist/server/internal/handlers/utils.d.ts +12 -0
- package/dist/server/internal/handlers/utils.d.ts.map +1 -0
- package/dist/server/internal/handlers/utils.js +80 -0
- package/dist/server/internal/handlers/utils.js.map +1 -0
- package/dist/server/internal/handlers/webAuthn.d.ts +57 -0
- package/dist/server/internal/handlers/webAuthn.d.ts.map +1 -0
- package/dist/server/internal/handlers/webAuthn.js +143 -0
- package/dist/server/internal/handlers/webAuthn.js.map +1 -0
- package/package.json +2 -2
- package/src/core/Provider.connect.browser.test.ts +23 -2
- package/src/core/adapters/dialog.ts +6 -1
- package/src/core/zod/rpc.ts +1 -1
- package/src/server/CliAuth.ts +1 -1
- package/src/server/Handler.test.ts +3 -418
- package/src/server/Handler.ts +5 -766
- package/src/server/internal/handlers/codeAuth.ts +148 -0
- package/src/server/internal/handlers/feePayer.test.ts +335 -0
- package/src/server/internal/handlers/feePayer.ts +271 -0
- package/src/server/internal/handlers/relay.test.ts +767 -0
- package/src/server/internal/handlers/relay.ts +817 -0
- package/src/server/internal/handlers/utils.ts +96 -0
- package/src/server/internal/handlers/webAuthn.test.ts +170 -0
- package/src/server/internal/handlers/webAuthn.ts +213 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codeAuth.d.ts","sourceRoot":"","sources":["../../../../src/server/internal/handlers/codeAuth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAU,SAAS,EAAE,MAAM,MAAM,CAAA;AAKpD,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,KAAK,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAErD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,QAAQ,CAAC,OAAY,GAAG,OAAO,CAsGhE;AAED,MAAM,CAAC,OAAO,WAAW,QAAQ,CAAC;IAChC,KAAY,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG;QACnC;;;;WAIG;QACH,MAAM,CAAC,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC,GAAG,SAAS,CAAA;QACjD,2CAA2C;QAC3C,GAAG,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAA;QAChC,qEAAqE;QACrE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QACzB,qEAAqE;QACrE,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,SAAS,CAAA;QACnC,6DAA6D;QAC7D,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,UAAU,CAAC,GAAG,SAAS,CAAA;QACnD,yBAAyB;QACzB,KAAK,CAAC,EAAE,OAAO,CAAC,KAAK,GAAG,SAAS,CAAA;QACjC,yEAAyE;QACzE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,SAAS,CAAA;QAClD,yDAAyD;QACzD,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC3B,CAAA;CACF"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { createClient, http } from 'viem';
|
|
2
|
+
import { tempo, tempoModerato } from 'viem/chains';
|
|
3
|
+
import * as z from 'zod/mini';
|
|
4
|
+
import * as CliAuth from '../../CliAuth.js';
|
|
5
|
+
import { from } from '../../Handler.js';
|
|
6
|
+
/**
|
|
7
|
+
* Instantiates a generic device-code handler for access-key bootstrap.
|
|
8
|
+
*
|
|
9
|
+
* Exposes 4 endpoints:
|
|
10
|
+
* - `GET /auth/pkce/pending/:code`
|
|
11
|
+
* - `POST /auth/pkce/code`
|
|
12
|
+
* - `POST /auth/pkce/poll/:code`
|
|
13
|
+
* - `POST /auth/pkce`
|
|
14
|
+
*
|
|
15
|
+
* @param options - Options.
|
|
16
|
+
* @returns Request handler.
|
|
17
|
+
*/
|
|
18
|
+
export function codeAuth(options = {}) {
|
|
19
|
+
const { chains = [tempo, tempoModerato], now, path = '/auth/pkce', policy, random, store = CliAuth.Store.memory(), transports = {}, ttlMs, ...rest } = options;
|
|
20
|
+
const clients = new Map();
|
|
21
|
+
for (const chain of chains) {
|
|
22
|
+
const transport = transports[chain.id] ?? http();
|
|
23
|
+
clients.set(chain.id, createClient({ chain, transport }));
|
|
24
|
+
}
|
|
25
|
+
function getClient(chainId) {
|
|
26
|
+
if (typeof chainId !== 'undefined') {
|
|
27
|
+
const id = Number(chainId);
|
|
28
|
+
const client = clients.get(id);
|
|
29
|
+
if (!client)
|
|
30
|
+
throw new Error(`Chain ${id} not configured`);
|
|
31
|
+
return client;
|
|
32
|
+
}
|
|
33
|
+
return clients.get(chains[0].id);
|
|
34
|
+
}
|
|
35
|
+
const router = from(rest);
|
|
36
|
+
router.get(`${path}/pending/:code`, async (c) => {
|
|
37
|
+
try {
|
|
38
|
+
const code = c.req.param('code');
|
|
39
|
+
const result = await CliAuth.pending({
|
|
40
|
+
code,
|
|
41
|
+
...(now ? { now } : {}),
|
|
42
|
+
store,
|
|
43
|
+
});
|
|
44
|
+
return Response.json(z.encode(CliAuth.pendingResponse, result));
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
const status = error instanceof CliAuth.PendingError ? error.status : 400;
|
|
48
|
+
return Response.json({ error: error.message }, { status });
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
router.post(`${path}/code`, async (c) => {
|
|
52
|
+
try {
|
|
53
|
+
const request = z.decode(CliAuth.createRequest, await c.req.raw.json());
|
|
54
|
+
const chainId = request.chainId ?? chains[0].id;
|
|
55
|
+
getClient(chainId);
|
|
56
|
+
const result = await CliAuth.createDeviceCode({
|
|
57
|
+
chainId,
|
|
58
|
+
...(now ? { now } : {}),
|
|
59
|
+
...(policy ? { policy } : {}),
|
|
60
|
+
...(random ? { random } : {}),
|
|
61
|
+
request,
|
|
62
|
+
store,
|
|
63
|
+
...(typeof ttlMs !== 'undefined' ? { ttlMs } : {}),
|
|
64
|
+
});
|
|
65
|
+
return Response.json(z.encode(CliAuth.createResponse, result));
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
return Response.json({ error: error.message }, { status: 400 });
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
router.post(`${path}/poll/:code`, async (c) => {
|
|
72
|
+
try {
|
|
73
|
+
const request = z.decode(CliAuth.pollRequest, await c.req.raw.json());
|
|
74
|
+
const code = c.req.param('code');
|
|
75
|
+
const result = await CliAuth.poll({
|
|
76
|
+
code,
|
|
77
|
+
...(now ? { now } : {}),
|
|
78
|
+
request,
|
|
79
|
+
store,
|
|
80
|
+
});
|
|
81
|
+
return Response.json(z.encode(CliAuth.pollResponse, result));
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
return Response.json({ error: error.message }, { status: 400 });
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
router.post(path, async (c) => {
|
|
88
|
+
try {
|
|
89
|
+
const request = z.decode(CliAuth.authorizeRequest, await c.req.raw.json());
|
|
90
|
+
const result = await CliAuth.authorize({
|
|
91
|
+
client: getClient(request.keyAuthorization.chainId),
|
|
92
|
+
...(now ? { now } : {}),
|
|
93
|
+
request,
|
|
94
|
+
store,
|
|
95
|
+
});
|
|
96
|
+
return Response.json(z.encode(CliAuth.authorizeResponse, result));
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
return Response.json({ error: error.message }, { status: 400 });
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
return router;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=codeAuth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codeAuth.js","sourceRoot":"","sources":["../../../../src/server/internal/handlers/codeAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { RpcRequest } from 'ox';
|
|
2
|
+
import type { Chain, Transport } from 'viem';
|
|
3
|
+
import type { LocalAccount } from 'viem/accounts';
|
|
4
|
+
import { Transaction } from 'viem/tempo';
|
|
5
|
+
import { type Handler, from } from '../../Handler.js';
|
|
6
|
+
/**
|
|
7
|
+
* Instantiates a fee payer service request handler that can be used to
|
|
8
|
+
* sponsor the fee for user transactions.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { privateKeyToAccount } from 'viem/accounts'
|
|
13
|
+
* import { Handler } from 'accounts/server'
|
|
14
|
+
*
|
|
15
|
+
* const handler = Handler.feePayer({
|
|
16
|
+
* account: privateKeyToAccount('0x...'),
|
|
17
|
+
* })
|
|
18
|
+
*
|
|
19
|
+
* // Plug handler into your server framework of choice:
|
|
20
|
+
* createServer(handler.listener) // Node.js
|
|
21
|
+
* Bun.serve(handler) // Bun
|
|
22
|
+
* Deno.serve(handler) // Deno
|
|
23
|
+
* app.use(handler.listener) // Express
|
|
24
|
+
* app.all('*', c => handler.fetch(c.req.raw)) // Hono
|
|
25
|
+
* export const GET = handler.fetch // Next.js
|
|
26
|
+
* export const POST = handler.fetch // Next.js
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @param options - Options.
|
|
30
|
+
* @returns Request handler.
|
|
31
|
+
*/
|
|
32
|
+
export declare function feePayer(options: feePayer.Options): Handler;
|
|
33
|
+
export declare namespace feePayer {
|
|
34
|
+
type Options = from.Options & {
|
|
35
|
+
/** Account to use as the fee payer. */
|
|
36
|
+
account: LocalAccount;
|
|
37
|
+
/**
|
|
38
|
+
* Supported chains. The handler resolves the client based on the
|
|
39
|
+
* `chainId` in the incoming transaction.
|
|
40
|
+
* @default [tempo, tempoModerato]
|
|
41
|
+
*/
|
|
42
|
+
chains?: readonly [Chain, ...Chain[]] | undefined;
|
|
43
|
+
/** Function to call before handling the request. */
|
|
44
|
+
onRequest?: (request: RpcRequest.RpcRequest) => Promise<void>;
|
|
45
|
+
/** Path to use for the handler. */
|
|
46
|
+
path?: string | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Validates whether to sponsor the transaction. When omitted, all
|
|
49
|
+
* transactions are sponsored. Return `false` to reject sponsorship.
|
|
50
|
+
*/
|
|
51
|
+
validate?: ((request: Transaction.TransactionRequest) => boolean | Promise<boolean>) | undefined;
|
|
52
|
+
/** Sponsor display name returned from `eth_fillTransaction`. */
|
|
53
|
+
name?: string | undefined;
|
|
54
|
+
/** Transports keyed by chain ID. Defaults to `http()` for each chain. */
|
|
55
|
+
transports?: Record<number, Transport> | undefined;
|
|
56
|
+
/** Sponsor URL returned from `eth_fillTransaction`. */
|
|
57
|
+
url?: string | undefined;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** Signs a filled transaction as the fee payer. */
|
|
61
|
+
export declare function sign(options: {
|
|
62
|
+
account: LocalAccount;
|
|
63
|
+
transaction: Record<string, unknown>;
|
|
64
|
+
sender?: `0x${string}` | undefined;
|
|
65
|
+
}): Promise<{
|
|
66
|
+
feePayerSignature: {
|
|
67
|
+
r: bigint;
|
|
68
|
+
s: bigint;
|
|
69
|
+
yParity: number;
|
|
70
|
+
};
|
|
71
|
+
from: `0x${string}` | undefined;
|
|
72
|
+
}>;
|
|
73
|
+
//# sourceMappingURL=feePayer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feePayer.d.ts","sourceRoot":"","sources":["../../../../src/server/internal/handlers/feePayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA0B,MAAM,IAAI,CAAA;AAEvD,OAAO,KAAK,EAAW,KAAK,EAAU,SAAS,EAAE,MAAM,MAAM,CAAA;AAE7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAGjD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAExC,OAAO,EAAE,KAAK,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAGrD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,GAAG,OAAO,CA+J3D;AAED,MAAM,CAAC,OAAO,WAAW,QAAQ,CAAC;IAChC,KAAK,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG;QAC5B,uCAAuC;QACvC,OAAO,EAAE,YAAY,CAAA;QACrB;;;;WAIG;QACH,MAAM,CAAC,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC,GAAG,SAAS,CAAA;QACjD,oDAAoD;QACpD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;QAC7D,mCAAmC;QACnC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QACzB;;;WAGG;QACH,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,WAAW,CAAC,kBAAkB,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAA;QAChG,gEAAgE;QAChE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QACzB,yEAAyE;QACzE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,SAAS,CAAA;QAClD,uDAAuD;QACvD,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KACzB,CAAA;CACF;AAED,mDAAmD;AACnD,wBAAsB,IAAI,CAAC,OAAO,EAAE;IAClC,OAAO,EAAE,YAAY,CAAA;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,MAAM,CAAC,EAAE,KAAK,MAAM,EAAE,GAAG,SAAS,CAAA;CACnC;;;;;;;GAqBA"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { RpcRequest, RpcResponse, Signature } from 'ox';
|
|
2
|
+
import { Transaction as core_Transaction, TxEnvelopeTempo } from 'ox/tempo';
|
|
3
|
+
import { createClient, http } from 'viem';
|
|
4
|
+
import { signTransaction } from 'viem/actions';
|
|
5
|
+
import { tempo, tempoModerato } from 'viem/chains';
|
|
6
|
+
import { Transaction } from 'viem/tempo';
|
|
7
|
+
import { from } from '../../Handler.js';
|
|
8
|
+
import * as Utils from './utils.js';
|
|
9
|
+
/**
|
|
10
|
+
* Instantiates a fee payer service request handler that can be used to
|
|
11
|
+
* sponsor the fee for user transactions.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { privateKeyToAccount } from 'viem/accounts'
|
|
16
|
+
* import { Handler } from 'accounts/server'
|
|
17
|
+
*
|
|
18
|
+
* const handler = Handler.feePayer({
|
|
19
|
+
* account: privateKeyToAccount('0x...'),
|
|
20
|
+
* })
|
|
21
|
+
*
|
|
22
|
+
* // Plug handler into your server framework of choice:
|
|
23
|
+
* createServer(handler.listener) // Node.js
|
|
24
|
+
* Bun.serve(handler) // Bun
|
|
25
|
+
* Deno.serve(handler) // Deno
|
|
26
|
+
* app.use(handler.listener) // Express
|
|
27
|
+
* app.all('*', c => handler.fetch(c.req.raw)) // Hono
|
|
28
|
+
* export const GET = handler.fetch // Next.js
|
|
29
|
+
* export const POST = handler.fetch // Next.js
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @param options - Options.
|
|
33
|
+
* @returns Request handler.
|
|
34
|
+
*/
|
|
35
|
+
export function feePayer(options) {
|
|
36
|
+
const { account, chains = [tempo, tempoModerato], name, onRequest, path = '/', validate, transports = {}, url, ...rest } = options;
|
|
37
|
+
const clients = new Map();
|
|
38
|
+
for (const chain of chains) {
|
|
39
|
+
const transport = transports[chain.id] ?? http();
|
|
40
|
+
clients.set(chain.id, createClient({ chain, transport }));
|
|
41
|
+
}
|
|
42
|
+
function getClient(chainId) {
|
|
43
|
+
if (chainId) {
|
|
44
|
+
const client = clients.get(chainId);
|
|
45
|
+
if (!client)
|
|
46
|
+
throw new Error(`Chain ${chainId} not configured`);
|
|
47
|
+
return client;
|
|
48
|
+
}
|
|
49
|
+
return clients.get(chains[0].id);
|
|
50
|
+
}
|
|
51
|
+
const sponsor = {
|
|
52
|
+
address: account.address,
|
|
53
|
+
...(name ? { name } : {}),
|
|
54
|
+
...(url ? { url } : {}),
|
|
55
|
+
};
|
|
56
|
+
const router = from(rest);
|
|
57
|
+
router.post(path, async (c) => {
|
|
58
|
+
const request = RpcRequest.from((await c.req.raw.json()));
|
|
59
|
+
try {
|
|
60
|
+
await onRequest?.(request);
|
|
61
|
+
const method = request.method;
|
|
62
|
+
if (method !== 'eth_fillTransaction' &&
|
|
63
|
+
method !== 'eth_signRawTransaction' &&
|
|
64
|
+
method !== 'eth_sendRawTransaction' &&
|
|
65
|
+
method !== 'eth_sendRawTransactionSync')
|
|
66
|
+
return Response.json(RpcResponse.from({
|
|
67
|
+
error: new RpcResponse.MethodNotSupportedError({
|
|
68
|
+
message: `Method not supported: ${request.method}`,
|
|
69
|
+
}),
|
|
70
|
+
}, { request }));
|
|
71
|
+
if (method === 'eth_fillTransaction') {
|
|
72
|
+
const [parameters] = Utils.parseParams.parse(request.params);
|
|
73
|
+
const chainId = Utils.resolveChainId(parameters.chainId);
|
|
74
|
+
const client = getClient(chainId);
|
|
75
|
+
const normalized = Utils.normalizeFillTransactionRequest(parameters);
|
|
76
|
+
const sender = typeof parameters.from === 'string' ? parameters.from : undefined;
|
|
77
|
+
let transaction = await (async () => {
|
|
78
|
+
if (isPreparedFeePayerTransaction(parameters))
|
|
79
|
+
return Utils.normalizeTempoTransaction(parameters);
|
|
80
|
+
const fillRequest = Utils.formatFillTransactionRequest(client, {
|
|
81
|
+
...normalized,
|
|
82
|
+
...(typeof chainId !== 'undefined' ? { chainId } : {}),
|
|
83
|
+
feePayer: true,
|
|
84
|
+
});
|
|
85
|
+
const result = (await client.request({
|
|
86
|
+
method: 'eth_fillTransaction',
|
|
87
|
+
params: [fillRequest],
|
|
88
|
+
}));
|
|
89
|
+
return Utils.normalizeTempoTransaction(result.tx);
|
|
90
|
+
})();
|
|
91
|
+
if (validate &&
|
|
92
|
+
// @ts-expect-error - TODO: Convert to `TransactionRequest` properly.
|
|
93
|
+
!(await validate({
|
|
94
|
+
...transaction,
|
|
95
|
+
from: sender,
|
|
96
|
+
}))) {
|
|
97
|
+
// Re-fill without feePayer so gas/nonce are correct for self-payment.
|
|
98
|
+
const fillRequest = Utils.formatFillTransactionRequest(client, {
|
|
99
|
+
...normalized,
|
|
100
|
+
...(typeof chainId !== 'undefined' ? { chainId } : {}),
|
|
101
|
+
});
|
|
102
|
+
const result = (await client.request({
|
|
103
|
+
method: 'eth_fillTransaction',
|
|
104
|
+
params: [fillRequest],
|
|
105
|
+
}));
|
|
106
|
+
transaction = Utils.normalizeTempoTransaction(result.tx);
|
|
107
|
+
return Utils.rpcResult(request, {
|
|
108
|
+
tx: core_Transaction.toRpc(transaction),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
const signed = await sign({ account, transaction, sender });
|
|
112
|
+
return Utils.rpcResult(request, {
|
|
113
|
+
sponsor,
|
|
114
|
+
tx: core_Transaction.toRpc(signed),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const serialized = request.params?.[0];
|
|
118
|
+
if (!serialized?.startsWith('0x76') && !serialized?.startsWith('0x78'))
|
|
119
|
+
throw new RpcResponse.InvalidParamsError({
|
|
120
|
+
message: 'Only Tempo (0x76/0x78) transactions are supported.',
|
|
121
|
+
});
|
|
122
|
+
const transaction = Transaction.deserialize(serialized);
|
|
123
|
+
if (!transaction.signature || !transaction.from)
|
|
124
|
+
throw new RpcResponse.InvalidParamsError({
|
|
125
|
+
message: 'Transaction must be signed by the sender before fee payer signing.',
|
|
126
|
+
});
|
|
127
|
+
if (validate && !(await validate(transaction)))
|
|
128
|
+
throw new RpcResponse.InvalidParamsError({
|
|
129
|
+
message: 'Sponsorship rejected.',
|
|
130
|
+
});
|
|
131
|
+
const client = getClient(transaction.chainId);
|
|
132
|
+
const serializedTransaction = toSerializedTransaction(await signTransaction(client, {
|
|
133
|
+
...transaction,
|
|
134
|
+
account,
|
|
135
|
+
feePayer: account,
|
|
136
|
+
}));
|
|
137
|
+
if (method === 'eth_signRawTransaction')
|
|
138
|
+
return Response.json(RpcResponse.from({ result: serializedTransaction }, { request }));
|
|
139
|
+
const result = await client.request({
|
|
140
|
+
method: method,
|
|
141
|
+
params: [serializedTransaction],
|
|
142
|
+
});
|
|
143
|
+
return Response.json(RpcResponse.from({ result }, { request }));
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
return Utils.rpcError(request, error);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
return router;
|
|
150
|
+
}
|
|
151
|
+
/** Signs a filled transaction as the fee payer. */
|
|
152
|
+
export async function sign(options) {
|
|
153
|
+
const { account, transaction, sender } = options;
|
|
154
|
+
const from = transaction.from ?? sender;
|
|
155
|
+
const { signature: _, ...withoutSenderSig } = transaction;
|
|
156
|
+
const prepared = { ...withoutSenderSig, from };
|
|
157
|
+
if (!prepared.from)
|
|
158
|
+
throw new RpcResponse.InvalidParamsError({
|
|
159
|
+
message: 'Transaction sender must be provided before fee payer signing.',
|
|
160
|
+
});
|
|
161
|
+
if (!account.sign)
|
|
162
|
+
throw new Error('Fee payer account cannot sign transactions.');
|
|
163
|
+
const feePayerSignature = Signature.from(await account.sign({
|
|
164
|
+
hash: TxEnvelopeTempo.getFeePayerSignPayload(TxEnvelopeTempo.from(prepared), {
|
|
165
|
+
sender: prepared.from,
|
|
166
|
+
}),
|
|
167
|
+
}));
|
|
168
|
+
return { ...prepared, feePayerSignature };
|
|
169
|
+
}
|
|
170
|
+
function isPreparedFeePayerTransaction(value) {
|
|
171
|
+
return (typeof value.from === 'string' &&
|
|
172
|
+
typeof Utils.resolveChainId(value.chainId) === 'number' &&
|
|
173
|
+
typeof value.gas !== 'undefined' &&
|
|
174
|
+
typeof value.nonce !== 'undefined' &&
|
|
175
|
+
(typeof value.maxFeePerGas !== 'undefined' || typeof value.gasPrice !== 'undefined'));
|
|
176
|
+
}
|
|
177
|
+
function toSerializedTransaction(value) {
|
|
178
|
+
if (typeof value === 'string')
|
|
179
|
+
return value;
|
|
180
|
+
if (value && typeof value === 'object' && 'raw' in value && typeof value.raw === 'string')
|
|
181
|
+
return value.raw;
|
|
182
|
+
throw new Error('Expected a serialized transaction result.');
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=feePayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feePayer.js","sourceRoot":"","sources":["../../../../src/server/internal/handlers/feePayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,IAAI,CAAA;AACvD,OAAO,EAAE,WAAW,IAAI,gBAAgB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE3E,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAEzC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAExC,OAAO,EAAgB,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAyB;IAChD,MAAM,EACJ,OAAO,EACP,MAAM,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,EAC/B,IAAI,EACJ,SAAS,EACT,IAAI,GAAG,GAAG,EACV,QAAQ,EACR,UAAU,GAAG,EAAE,EACf,GAAG,EACH,GAAG,IAAI,EACR,GAAG,OAAO,CAAA;IAEX,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAA;IACzC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAA;QAChD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,YAAY,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;IAC3D,CAAC;IAED,SAAS,SAAS,CAAC,OAAgB;QACjC,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACnC,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,SAAS,OAAO,iBAAiB,CAAC,CAAA;YAC/D,OAAO,MAAM,CAAA;QACf,CAAC;QACD,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,EAAE,CAAE,CAAA;IACpC,CAAC;IAED,MAAM,OAAO,GAAG;QACd,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxB,CAAA;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAA;IAEzB,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC5B,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAQ,CAAC,CAAA;QAEhE,IAAI,CAAC;YACH,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC,CAAA;YAE1B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAgB,CAAA;YACvC,IACE,MAAM,KAAK,qBAAqB;gBAChC,MAAM,KAAK,wBAAwB;gBACnC,MAAM,KAAK,wBAAwB;gBACnC,MAAM,KAAK,4BAA4B;gBAEvC,OAAO,QAAQ,CAAC,IAAI,CAClB,WAAW,CAAC,IAAI,CACd;oBACE,KAAK,EAAE,IAAI,WAAW,CAAC,uBAAuB,CAAC;wBAC7C,OAAO,EAAE,yBAAyB,OAAO,CAAC,MAAM,EAAE;qBACnD,CAAC;iBACH,EACD,EAAE,OAAO,EAAE,CACZ,CACF,CAAA;YAEH,IAAI,MAAM,KAAK,qBAAqB,EAAE,CAAC;gBACrC,MAAM,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAA8B,CAAA;gBACzF,MAAM,OAAO,GAAG,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;gBACxD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;gBACjC,MAAM,UAAU,GAAG,KAAK,CAAC,+BAA+B,CAAC,UAAU,CAAC,CAAA;gBACpE,MAAM,MAAM,GACV,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,UAAU,CAAC,IAAgB,CAAC,CAAC,CAAC,SAAS,CAAA;gBAEhF,IAAI,WAAW,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE;oBAClC,IAAI,6BAA6B,CAAC,UAAU,CAAC;wBAC3C,OAAO,KAAK,CAAC,yBAAyB,CAAC,UAAU,CAAC,CAAA;oBAEpD,MAAM,WAAW,GAAG,KAAK,CAAC,4BAA4B,CAAC,MAAM,EAAE;wBAC7D,GAAG,UAAU;wBACb,GAAG,CAAC,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACtD,QAAQ,EAAE,IAAI;qBACf,CAAC,CAAA;oBACF,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC;wBACnC,MAAM,EAAE,qBAA8B;wBACtC,MAAM,EAAE,CAAC,WAAW,CAAC;qBACtB,CAAC,CAAiD,CAAA;oBACnD,OAAO,KAAK,CAAC,yBAAyB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;gBACnD,CAAC,CAAC,EAAE,CAAA;gBAEJ,IACE,QAAQ;oBACR,qEAAqE;oBACrE,CAAC,CAAC,MAAM,QAAQ,CAAC;wBACf,GAAG,WAAW;wBACd,IAAI,EAAE,MAAM;qBACqB,CAAC,CAAC,EACrC,CAAC;oBACD,sEAAsE;oBACtE,MAAM,WAAW,GAAG,KAAK,CAAC,4BAA4B,CAAC,MAAM,EAAE;wBAC7D,GAAG,UAAU;wBACb,GAAG,CAAC,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACvD,CAAC,CAAA;oBACF,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC;wBACnC,MAAM,EAAE,qBAA8B;wBACtC,MAAM,EAAE,CAAC,WAAW,CAAC;qBACtB,CAAC,CAAiD,CAAA;oBACnD,WAAW,GAAG,KAAK,CAAC,yBAAyB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;oBAExD,OAAO,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE;wBAC9B,EAAE,EAAE,gBAAgB,CAAC,KAAK,CAAC,WAA2C,CAAC;qBACxE,CAAC,CAAA;gBACJ,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAA;gBAE3D,OAAO,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE;oBAC9B,OAAO;oBACP,EAAE,EAAE,gBAAgB,CAAC,KAAK,CAAC,MAAsC,CAAC;iBACnE,CAAC,CAAA;YACJ,CAAC;YAED,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAgC,CAAA;YAErE,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC;gBACpE,MAAM,IAAI,WAAW,CAAC,kBAAkB,CAAC;oBACvC,OAAO,EAAE,oDAAoD;iBAC9D,CAAC,CAAA;YAEJ,MAAM,WAAW,GAAG,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,CAAA;YAEvD,IAAI,CAAC,WAAW,CAAC,SAAS,IAAI,CAAC,WAAW,CAAC,IAAI;gBAC7C,MAAM,IAAI,WAAW,CAAC,kBAAkB,CAAC;oBACvC,OAAO,EAAE,oEAAoE;iBAC9E,CAAC,CAAA;YAEJ,IAAI,QAAQ,IAAI,CAAC,CAAC,MAAM,QAAQ,CAAC,WAA6C,CAAC,CAAC;gBAC9E,MAAM,IAAI,WAAW,CAAC,kBAAkB,CAAC;oBACvC,OAAO,EAAE,uBAAuB;iBACjC,CAAC,CAAA;YAEJ,MAAM,MAAM,GAAG,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;YAC7C,MAAM,qBAAqB,GAAG,uBAAuB,CACnD,MAAM,eAAe,CAAC,MAAM,EAAE;gBAC5B,GAAG,WAAW;gBACd,OAAO;gBACP,QAAQ,EAAE,OAAO;aACT,CAAC,CACZ,CAAA;YAED,IAAI,MAAM,KAAK,wBAAwB;gBACrC,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,qBAAqB,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;YAExF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;gBAClC,MAAM,EAAE,MAAe;gBACvB,MAAM,EAAE,CAAC,qBAAqB,CAAC;aAChC,CAAC,CAAA;YAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;QACjE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QACvC,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC;AA8BD,mDAAmD;AACnD,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAI1B;IACC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IAChD,MAAM,IAAI,GAAI,WAAW,CAAC,IAAkC,IAAI,MAAM,CAAA;IACtE,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,gBAAgB,EAAE,GAAG,WAAW,CAAA;IACzD,MAAM,QAAQ,GAAG,EAAE,GAAG,gBAAgB,EAAE,IAAI,EAAE,CAAA;IAE9C,IAAI,CAAC,QAAQ,CAAC,IAAI;QAChB,MAAM,IAAI,WAAW,CAAC,kBAAkB,CAAC;YACvC,OAAO,EAAE,+DAA+D;SACzE,CAAC,CAAA;IACJ,IAAI,CAAC,OAAO,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;IAEjF,MAAM,iBAAiB,GAAG,SAAS,CAAC,IAAI,CACtC,MAAM,OAAO,CAAC,IAAI,CAAC;QACjB,IAAI,EAAE,eAAe,CAAC,sBAAsB,CAAC,eAAe,CAAC,IAAI,CAAC,QAAiB,CAAC,EAAE;YACpF,MAAM,EAAE,QAAQ,CAAC,IAAI;SACtB,CAAC;KACH,CAAC,CACH,CAAA;IAED,OAAO,EAAE,GAAG,QAAQ,EAAE,iBAAiB,EAAE,CAAA;AAC3C,CAAC;AAED,SAAS,6BAA6B,CAAC,KAA8B;IACnE,OAAO,CACL,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,OAAO,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,QAAQ;QACvD,OAAO,KAAK,CAAC,GAAG,KAAK,WAAW;QAChC,OAAO,KAAK,CAAC,KAAK,KAAK,WAAW;QAClC,CAAC,OAAO,KAAK,CAAC,YAAY,KAAK,WAAW,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,WAAW,CAAC,CACrF,CAAA;AACH,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ;QACvF,OAAO,KAAK,CAAC,GAAG,CAAA;IAClB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAA;AAC9D,CAAC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Hex, RpcRequest } from 'ox';
|
|
2
|
+
import { type Address, type Chain, type Transport } from 'viem';
|
|
3
|
+
import { type Handler, from } from '../../Handler.js';
|
|
4
|
+
import * as FeePayer from './feePayer.js';
|
|
5
|
+
/**
|
|
6
|
+
* Instantiates a relay handler that proxies `eth_fillTransaction`
|
|
7
|
+
* with wallet-aware enrichment (fee token resolution, simulation,
|
|
8
|
+
* sponsorship, AMM resolution).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { Handler } from 'accounts/server'
|
|
13
|
+
*
|
|
14
|
+
* const handler = Handler.relay()
|
|
15
|
+
*
|
|
16
|
+
* // Plug handler into your server framework of choice:
|
|
17
|
+
* createServer(handler.listener) // Node.js
|
|
18
|
+
* Bun.serve(handler) // Bun
|
|
19
|
+
* Deno.serve(handler) // Deno
|
|
20
|
+
* app.use(handler.listener) // Express
|
|
21
|
+
* app.all('*', c => handler.fetch(c.req.raw)) // Hono
|
|
22
|
+
* export const GET = handler.fetch // Next.js
|
|
23
|
+
* export const POST = handler.fetch // Next.js
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* With sponsorship
|
|
28
|
+
*
|
|
29
|
+
* ```ts
|
|
30
|
+
* import { privateKeyToAccount } from 'viem/accounts'
|
|
31
|
+
* import { Handler } from 'accounts/server'
|
|
32
|
+
*
|
|
33
|
+
* // With sponsorship — signs as fee payer when `validate` approves.
|
|
34
|
+
* const handler = Handler.relay({
|
|
35
|
+
* feePayer: {
|
|
36
|
+
* account: privateKeyToAccount('0x...'),
|
|
37
|
+
* // Optional: validate sponsorship approval.
|
|
38
|
+
* // validate: (request) => request.from !== BLOCKED_ADDRESS,
|
|
39
|
+
* },
|
|
40
|
+
* })
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @param options - Options.
|
|
44
|
+
* @returns Request handler.
|
|
45
|
+
*/
|
|
46
|
+
export declare function relay(options?: relay.Options): Handler;
|
|
47
|
+
export declare namespace relay {
|
|
48
|
+
/** Default token lists per chain ID for fee token resolution. */
|
|
49
|
+
const defaultTokens: {
|
|
50
|
+
readonly 4217: readonly ["0x20c0000000000000000000000000000000000000", "0x20c000000000000000000000b9537d11c60e8b50", "0x20c0000000000000000000001621e21f71cf12fb", "0x20c00000000000000000000014f22ca97301eb73", "0x20c0000000000000000000003554d28269e0f3c2", "0x20c0000000000000000000000520792dcccccccc", "0x20c0000000000000000000008ee4fcff88888888", "0x20c0000000000000000000005c0bac7cef389a11", "0x20c0000000000000000000007f7ba549dd0251b9", "0x20c000000000000000000000aeed2ec36a54d0e5", "0x20c0000000000000000000009a4a4b17e0dc6651", "0x20c000000000000000000000383a23bacb546ab9"];
|
|
51
|
+
readonly 42431: readonly ["0x20c0000000000000000000000000000000000000", "0x20c0000000000000000000000000000000000001", "0x20c0000000000000000000000000000000000002", "0x20c0000000000000000000000000000000000003", "0x20c0000000000000000000009e8d7eb59b783726", "0x20c000000000000000000000d72572838bbee59c"];
|
|
52
|
+
readonly 1337: readonly ["0x20c0000000000000000000000000000000000000", "0x20c0000000000000000000000000000000000001", "0x20c0000000000000000000000000000000000002", "0x20c0000000000000000000000000000000000003"];
|
|
53
|
+
};
|
|
54
|
+
type Options = from.Options & {
|
|
55
|
+
/**
|
|
56
|
+
* Supported chains. The handler resolves the client based on the
|
|
57
|
+
* `chainId` in the incoming transaction.
|
|
58
|
+
* @default [tempo, tempoModerato]
|
|
59
|
+
*/
|
|
60
|
+
chains?: readonly [Chain, ...Chain[]] | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Fee payer / sponsor configuration. When provided, the relay will
|
|
63
|
+
* sign `feePayerSignature` on the filled transaction.
|
|
64
|
+
*/
|
|
65
|
+
feePayer?: Omit<FeePayer.feePayer.Options, 'chains' | 'transports' | 'path' | 'onRequest'> | undefined;
|
|
66
|
+
/** AMM swap options for automatic InsufficientBalance resolution. */
|
|
67
|
+
feeSwap?: {
|
|
68
|
+
/** Slippage tolerance (e.g. 0.05 = 5%). @default 0.05 */
|
|
69
|
+
slippage?: number | undefined;
|
|
70
|
+
} | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Returns token addresses to check balances for during fee token resolution.
|
|
73
|
+
* The relay checks `balanceOf` for each token and picks the one with the
|
|
74
|
+
* highest balance.
|
|
75
|
+
*/
|
|
76
|
+
resolveTokens?: ((chainId?: number | undefined) => readonly Address[]) | undefined;
|
|
77
|
+
/** Function to call before handling the request. */
|
|
78
|
+
onRequest?: ((request: RpcRequest.RpcRequest) => Promise<void>) | undefined;
|
|
79
|
+
/** Path to use for the handler. @default "/" */
|
|
80
|
+
path?: string | undefined;
|
|
81
|
+
/** Transports keyed by chain ID. Defaults to `http()` for each chain. */
|
|
82
|
+
transports?: Record<number, Transport> | undefined;
|
|
83
|
+
};
|
|
84
|
+
/** Metadata returned alongside the filled transaction. */
|
|
85
|
+
type Meta = {
|
|
86
|
+
/** Per-account balance diffs keyed by address. */
|
|
87
|
+
balanceDiffs?: Record<Address, readonly BalanceDiff[]> | undefined;
|
|
88
|
+
/** Fee estimate for the transaction. */
|
|
89
|
+
fee: {
|
|
90
|
+
amount: Hex.Hex;
|
|
91
|
+
decimals: number;
|
|
92
|
+
formatted: string;
|
|
93
|
+
symbol: string;
|
|
94
|
+
} | null;
|
|
95
|
+
/** Whether the transaction is sponsored by a fee payer. */
|
|
96
|
+
sponsored: boolean;
|
|
97
|
+
/** Sponsor details (when sponsored). */
|
|
98
|
+
sponsor?: {
|
|
99
|
+
address: Address;
|
|
100
|
+
name: string;
|
|
101
|
+
url: string;
|
|
102
|
+
} | undefined;
|
|
103
|
+
/** AMM swap injected by the relay to cover an InsufficientBalance. */
|
|
104
|
+
feeSwap?: {
|
|
105
|
+
/** Max input amount with slippage. */
|
|
106
|
+
maxIn: SwapAmount;
|
|
107
|
+
/** Deficit amount that triggered the swap. */
|
|
108
|
+
minOut: SwapAmount;
|
|
109
|
+
/** Slippage tolerance (e.g. 0.1 = 10%). */
|
|
110
|
+
slippage: number;
|
|
111
|
+
} | undefined;
|
|
112
|
+
};
|
|
113
|
+
/** Token amount in a fee swap. */
|
|
114
|
+
type SwapAmount = {
|
|
115
|
+
/** Token address. */
|
|
116
|
+
token: Address;
|
|
117
|
+
/** Amount (hex-encoded). */
|
|
118
|
+
value: Hex.Hex;
|
|
119
|
+
/** Human-readable formatted amount. */
|
|
120
|
+
formatted: string;
|
|
121
|
+
/** Token decimals. */
|
|
122
|
+
decimals: number;
|
|
123
|
+
/** Token symbol (e.g. "USDC.e"). */
|
|
124
|
+
symbol: string;
|
|
125
|
+
/** Token name (e.g. "USDC.e"). */
|
|
126
|
+
name: string;
|
|
127
|
+
};
|
|
128
|
+
/** Balance diff for a single token relative to the user account. */
|
|
129
|
+
type BalanceDiff = {
|
|
130
|
+
/** Token address. */
|
|
131
|
+
address: Address;
|
|
132
|
+
/** Token decimals (e.g. 6). */
|
|
133
|
+
decimals: number;
|
|
134
|
+
/** Direction relative to the user. */
|
|
135
|
+
direction: 'incoming' | 'outgoing';
|
|
136
|
+
/** Human-readable formatted currency value (e.g. "100.00"). */
|
|
137
|
+
formatted: string;
|
|
138
|
+
/** Token name (e.g. "USDC.e"). */
|
|
139
|
+
name: string;
|
|
140
|
+
/** Addresses receiving this asset. */
|
|
141
|
+
recipients: readonly Address[];
|
|
142
|
+
/** Token symbol (e.g. "USDC.e"). */
|
|
143
|
+
symbol: string;
|
|
144
|
+
/** Token amount (hex-encoded). */
|
|
145
|
+
value: Hex.Hex;
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=relay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../../../src/server/internal/handlers/relay.ts"],"names":[],"mappings":"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"}
|