accounts 0.6.7 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/core/ExecutionError.d.ts +25 -0
- package/dist/core/ExecutionError.d.ts.map +1 -0
- package/dist/core/ExecutionError.js +170 -0
- package/dist/core/ExecutionError.js.map +1 -0
- package/dist/core/Schema.d.ts +33 -7
- package/dist/core/Schema.d.ts.map +1 -1
- package/dist/core/zod/rpc.d.ts +14 -1
- package/dist/core/zod/rpc.d.ts.map +1 -1
- package/dist/core/zod/rpc.js +14 -1
- package/dist/core/zod/rpc.js.map +1 -1
- package/dist/server/CliAuth.d.ts +110 -43
- package/dist/server/CliAuth.d.ts.map +1 -1
- package/dist/server/CliAuth.js +243 -155
- package/dist/server/CliAuth.js.map +1 -1
- package/dist/server/Handler.d.ts +0 -1
- package/dist/server/Handler.d.ts.map +1 -1
- package/dist/server/Handler.js +0 -1
- package/dist/server/Handler.js.map +1 -1
- package/dist/server/internal/handlers/relay.d.ts +29 -12
- package/dist/server/internal/handlers/relay.d.ts.map +1 -1
- package/dist/server/internal/handlers/relay.js +180 -125
- package/dist/server/internal/handlers/relay.js.map +1 -1
- package/dist/server/internal/handlers/sponsorship.d.ts +77 -0
- package/dist/server/internal/handlers/sponsorship.d.ts.map +1 -0
- package/dist/server/internal/handlers/sponsorship.js +96 -0
- package/dist/server/internal/handlers/sponsorship.js.map +1 -0
- package/dist/server/internal/handlers/utils.d.ts +3 -1
- package/dist/server/internal/handlers/utils.d.ts.map +1 -1
- package/dist/server/internal/handlers/utils.js +15 -12
- package/dist/server/internal/handlers/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/core/ExecutionError.test.ts +205 -0
- package/src/core/ExecutionError.ts +189 -0
- package/src/core/Provider.test.ts +4 -2
- package/src/core/zod/rpc.ts +18 -1
- package/src/server/CliAuth.test-d.ts +6 -0
- package/src/server/CliAuth.test.ts +83 -0
- package/src/server/CliAuth.ts +331 -208
- package/src/server/Handler.ts +0 -1
- package/src/server/internal/handlers/relay.test.ts +318 -108
- package/src/server/internal/handlers/relay.ts +243 -138
- package/src/server/internal/handlers/sponsorship.ts +172 -0
- package/src/server/internal/handlers/utils.ts +15 -10
- package/dist/server/internal/handlers/feePayer.d.ts +0 -73
- package/dist/server/internal/handlers/feePayer.d.ts.map +0 -1
- package/dist/server/internal/handlers/feePayer.js +0 -184
- package/dist/server/internal/handlers/feePayer.js.map +0 -1
- package/src/server/internal/handlers/feePayer.test.ts +0 -336
- package/src/server/internal/handlers/feePayer.ts +0 -271
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { RpcResponse, Signature } from 'ox'
|
|
2
|
+
import { TxEnvelopeTempo } from 'ox/tempo'
|
|
3
|
+
import type { Address, Client } from 'viem'
|
|
4
|
+
import type { LocalAccount } from 'viem/accounts'
|
|
5
|
+
import { signTransaction } from 'viem/actions'
|
|
6
|
+
import { Transaction } from 'viem/tempo'
|
|
7
|
+
|
|
8
|
+
import * as Utils from './utils.js'
|
|
9
|
+
|
|
10
|
+
/** Returns sponsor metadata for `eth_fillTransaction` responses. */
|
|
11
|
+
export function getSponsor(options: getSponsor.Options): getSponsor.ReturnType {
|
|
12
|
+
const { account, name, url } = options
|
|
13
|
+
return {
|
|
14
|
+
address: account.address,
|
|
15
|
+
...(name ? { name } : {}),
|
|
16
|
+
...(url ? { url } : {}),
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export declare namespace getSponsor {
|
|
21
|
+
type Options = {
|
|
22
|
+
/** Account used for sponsorship. */
|
|
23
|
+
account: LocalAccount
|
|
24
|
+
/** Optional display name. */
|
|
25
|
+
name?: string | undefined
|
|
26
|
+
/** Optional display URL. */
|
|
27
|
+
url?: string | undefined
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
type ReturnType = {
|
|
31
|
+
/** Sponsor address. */
|
|
32
|
+
address: Address
|
|
33
|
+
/** Sponsor display name. */
|
|
34
|
+
name?: string | undefined
|
|
35
|
+
/** Sponsor display URL. */
|
|
36
|
+
url?: string | undefined
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Returns whether the fee payer approves a filled transaction. */
|
|
41
|
+
export async function shouldSponsor(options: shouldSponsor.Options) {
|
|
42
|
+
const { sender, transaction, validate } = options
|
|
43
|
+
if (!validate) return true
|
|
44
|
+
return await validate({
|
|
45
|
+
...transaction,
|
|
46
|
+
from: sender,
|
|
47
|
+
} as Transaction.TransactionRequest)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export declare namespace shouldSponsor {
|
|
51
|
+
type Options = {
|
|
52
|
+
/** Sender address from the original request. */
|
|
53
|
+
sender?: Address | undefined
|
|
54
|
+
/** Filled transaction to validate. */
|
|
55
|
+
transaction: Record<string, unknown>
|
|
56
|
+
/** Optional sponsorship approval callback. */
|
|
57
|
+
validate?: ((request: Transaction.TransactionRequest) => boolean | Promise<boolean>) | undefined
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Returns whether a raw Tempo transaction is explicitly requesting sponsorship. */
|
|
62
|
+
export function requestsRawSponsorship(serialized: `0x${string}`) {
|
|
63
|
+
if (!serialized.startsWith('0x76') && !serialized.startsWith('0x78')) return false
|
|
64
|
+
const transaction = Transaction.deserialize(serialized as `0x76${string}`)
|
|
65
|
+
return 'feePayerSignature' in transaction && transaction.feePayerSignature === null
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Returns `true` when a fill request already has the fields needed for sponsorship signing. */
|
|
69
|
+
export function isPreparedTransaction(value: Record<string, unknown>) {
|
|
70
|
+
return (
|
|
71
|
+
typeof value.from === 'string' &&
|
|
72
|
+
typeof Utils.resolveChainId(value.chainId) === 'number' &&
|
|
73
|
+
typeof value.gas !== 'undefined' &&
|
|
74
|
+
typeof value.nonce !== 'undefined' &&
|
|
75
|
+
(typeof value.maxFeePerGas !== 'undefined' || typeof value.gasPrice !== 'undefined')
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Signs a filled transaction as the fee payer. */
|
|
80
|
+
export async function sign(options: sign.Options) {
|
|
81
|
+
const { account, transaction, sender } = options
|
|
82
|
+
const from = (transaction.from as Address | undefined) ?? sender
|
|
83
|
+
const { signature: _, ...withoutSenderSig } = transaction
|
|
84
|
+
const prepared = { ...withoutSenderSig, from }
|
|
85
|
+
|
|
86
|
+
if (!prepared.from)
|
|
87
|
+
throw new RpcResponse.InvalidParamsError({
|
|
88
|
+
message: 'Transaction sender must be provided before fee payer signing.',
|
|
89
|
+
})
|
|
90
|
+
if (!account.sign) throw new Error('Fee payer account cannot sign transactions.')
|
|
91
|
+
|
|
92
|
+
const feePayerSignature = Signature.from(
|
|
93
|
+
await account.sign({
|
|
94
|
+
hash: TxEnvelopeTempo.getFeePayerSignPayload(TxEnvelopeTempo.from(prepared as never), {
|
|
95
|
+
sender: prepared.from,
|
|
96
|
+
}),
|
|
97
|
+
}),
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
return { ...prepared, feePayerSignature }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export declare namespace sign {
|
|
104
|
+
type Options = {
|
|
105
|
+
/** Account used as the fee payer. */
|
|
106
|
+
account: LocalAccount
|
|
107
|
+
/** Filled transaction to sign. */
|
|
108
|
+
transaction: Record<string, unknown>
|
|
109
|
+
/** Sender address from the original request. */
|
|
110
|
+
sender?: Address | undefined
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Handles `eth_signRawTransaction` and broadcast methods for sponsored Tempo transactions. */
|
|
115
|
+
export async function handleRawTransaction(options: handleRawTransaction.Options) {
|
|
116
|
+
const { account, getClient, method, request, validate } = options
|
|
117
|
+
const serialized = request.params?.[0] as `0x76${string}` | undefined
|
|
118
|
+
|
|
119
|
+
if (!serialized?.startsWith('0x76') && !serialized?.startsWith('0x78'))
|
|
120
|
+
throw new RpcResponse.InvalidParamsError({
|
|
121
|
+
message: 'Only Tempo (0x76/0x78) transactions are supported.',
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
const transaction = Transaction.deserialize(serialized)
|
|
125
|
+
|
|
126
|
+
if (!transaction.signature || !transaction.from)
|
|
127
|
+
throw new RpcResponse.InvalidParamsError({
|
|
128
|
+
message: 'Transaction must be signed by the sender before fee payer signing.',
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
if (validate && !(await validate(transaction as Transaction.TransactionRequest)))
|
|
132
|
+
throw new RpcResponse.InvalidParamsError({
|
|
133
|
+
message: 'Sponsorship rejected.',
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
const client = getClient(transaction.chainId)
|
|
137
|
+
const serializedTransaction = toSerializedTransaction(
|
|
138
|
+
await signTransaction(client, {
|
|
139
|
+
...transaction,
|
|
140
|
+
account,
|
|
141
|
+
feePayer: account,
|
|
142
|
+
} as never),
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
if (method === 'eth_signRawTransaction') return serializedTransaction
|
|
146
|
+
return await client.request({
|
|
147
|
+
method: method as never,
|
|
148
|
+
params: [serializedTransaction],
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export declare namespace handleRawTransaction {
|
|
153
|
+
type Options = {
|
|
154
|
+
/** Account used as the fee payer. */
|
|
155
|
+
account: LocalAccount
|
|
156
|
+
/** Client resolver keyed by transaction `chainId`. */
|
|
157
|
+
getClient: (chainId?: number | undefined) => Client
|
|
158
|
+
/** Raw transaction method to handle. */
|
|
159
|
+
method: 'eth_signRawTransaction' | 'eth_sendRawTransaction' | 'eth_sendRawTransactionSync'
|
|
160
|
+
/** Incoming JSON-RPC request. */
|
|
161
|
+
request: { params?: readonly unknown[] | undefined }
|
|
162
|
+
/** Optional sponsorship approval callback. */
|
|
163
|
+
validate?: ((request: Transaction.TransactionRequest) => boolean | Promise<boolean>) | undefined
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function toSerializedTransaction(value: unknown) {
|
|
168
|
+
if (typeof value === 'string') return value
|
|
169
|
+
if (value && typeof value === 'object' && 'raw' in value && typeof value.raw === 'string')
|
|
170
|
+
return value.raw
|
|
171
|
+
throw new Error('Expected a serialized transaction result.')
|
|
172
|
+
}
|
|
@@ -16,17 +16,22 @@ export function formatFillTransactionRequest(client: Client, value: Record<strin
|
|
|
16
16
|
return format({ ...value } as never, 'fillTransaction') as Record<string, unknown>
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export function normalizeFillTransactionRequest(
|
|
20
|
-
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
export function normalizeFillTransactionRequest(tx: Record<string, unknown>) {
|
|
20
|
+
const { to, data, value, ...rest } = tx
|
|
21
|
+
if (Array.isArray(tx.calls) && tx.calls.length > 0)
|
|
22
|
+
return {
|
|
23
|
+
...tx,
|
|
24
|
+
calls: tx.calls.map((call) => ({
|
|
25
|
+
...call,
|
|
26
|
+
value: normalizeFillValue(call.value),
|
|
27
|
+
})),
|
|
28
|
+
}
|
|
29
|
+
const call = {
|
|
30
|
+
...(typeof to !== 'undefined' ? { to } : {}),
|
|
31
|
+
...(typeof data !== 'undefined' ? { data } : {}),
|
|
32
|
+
...(typeof value !== 'undefined' ? { value: normalizeFillValue(value) } : {}),
|
|
29
33
|
}
|
|
34
|
+
return { ...rest, calls: [call] }
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
function normalizeFillValue(value: unknown) {
|
|
@@ -1,73 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,184 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"feePayer.js","sourceRoot":"","sources":["../../../../src/server/internal/handlers/feePayer.ts"],"names":[],"mappings":"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"}
|