accounts 0.18.4 → 0.19.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 +20 -0
- package/dist/core/AccessKey.d.ts +5 -1
- package/dist/core/AccessKey.d.ts.map +1 -1
- package/dist/core/AccessKey.js +2 -0
- package/dist/core/AccessKey.js.map +1 -1
- package/dist/core/Adapter.d.ts +4 -0
- package/dist/core/Adapter.d.ts.map +1 -1
- package/dist/core/Client.d.ts.map +1 -1
- package/dist/core/Client.js +62 -2
- package/dist/core/Client.js.map +1 -1
- package/dist/core/ExecutionError.d.ts.map +1 -1
- package/dist/core/ExecutionError.js +38 -3
- package/dist/core/ExecutionError.js.map +1 -1
- package/dist/core/Provider.d.ts.map +1 -1
- package/dist/core/Provider.js +16 -4
- package/dist/core/Provider.js.map +1 -1
- package/dist/core/Schema.d.ts +43 -0
- package/dist/core/Schema.d.ts.map +1 -1
- package/dist/core/adapters/privy.d.ts.map +1 -1
- package/dist/core/adapters/privy.js +7 -2
- package/dist/core/adapters/privy.js.map +1 -1
- package/dist/core/zod/rpc.d.ts +18 -0
- package/dist/core/zod/rpc.d.ts.map +1 -1
- package/dist/core/zod/rpc.js +13 -2
- package/dist/core/zod/rpc.js.map +1 -1
- package/dist/react/Remote.d.ts.map +1 -1
- package/dist/react/Remote.js +5 -1
- package/dist/react/Remote.js.map +1 -1
- package/dist/server/CliAuth.d.ts.map +1 -1
- package/dist/server/CliAuth.js +6 -4
- package/dist/server/CliAuth.js.map +1 -1
- package/dist/server/internal/handlers/relay.d.ts +0 -7
- package/dist/server/internal/handlers/relay.d.ts.map +1 -1
- package/dist/server/internal/handlers/relay.js +0 -46
- package/dist/server/internal/handlers/relay.js.map +1 -1
- package/dist/server/internal/handlers/sponsorship.d.ts +0 -2
- package/dist/server/internal/handlers/sponsorship.d.ts.map +1 -1
- package/dist/server/internal/handlers/sponsorship.js +1 -2
- package/dist/server/internal/handlers/sponsorship.js.map +1 -1
- package/dist/trusted-hosts.json +1 -0
- package/package.json +5 -5
- package/src/cli/Provider.localnet.test.ts +3 -3
- package/src/core/AccessKey.permissions.test.ts +73 -0
- package/src/core/AccessKey.test.ts +29 -27
- package/src/core/AccessKey.ts +7 -1
- package/src/core/Adapter.ts +4 -0
- package/src/core/Client.test.ts +153 -1
- package/src/core/Client.ts +73 -2
- package/src/core/ExecutionError.ts +39 -3
- package/src/core/Provider.localnet.test.ts +116 -1
- package/src/core/Provider.ts +25 -8
- package/src/core/Schema.test-d.ts +14 -0
- package/src/core/adapters/deviceCode/deviceCode.localnet.test.ts +4 -1
- package/src/core/adapters/privy.test.ts +150 -8
- package/src/core/adapters/privy.ts +13 -5
- package/src/core/zod/request.test.ts +26 -0
- package/src/core/zod/rpc.ts +15 -4
- package/src/react/Remote.test.ts +153 -0
- package/src/react/Remote.ts +7 -1
- package/src/server/CliAuth.test.ts +5 -3
- package/src/server/CliAuth.ts +6 -4
- package/src/server/internal/handlers/relay.ts +0 -56
- package/src/server/internal/handlers/sponsorship.ts +1 -4
- package/src/trusted-hosts.json +1 -0
- package/dist/server/internal/handlers/multisig.d.ts +0 -214
- package/dist/server/internal/handlers/multisig.d.ts.map +0 -1
- package/dist/server/internal/handlers/multisig.js +0 -505
- package/dist/server/internal/handlers/multisig.js.map +0 -1
- package/src/server/internal/handlers/multisig.localnet.test.ts +0 -94
- package/src/server/internal/handlers/multisig.test.ts +0 -743
- package/src/server/internal/handlers/multisig.ts +0 -774
|
@@ -570,13 +570,21 @@ export function privy<const client extends privy.Client>(
|
|
|
570
570
|
},
|
|
571
571
|
async revokeAccessKey(parameters) {
|
|
572
572
|
const account = await getSigningAccount(parameters.address)
|
|
573
|
+
const { feePayer } = parameters
|
|
573
574
|
try {
|
|
574
|
-
await Actions.accessKey.revoke(
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
575
|
+
await Actions.accessKey.revoke(
|
|
576
|
+
getClient({ feePayer: feePayer === true ? undefined : feePayer }),
|
|
577
|
+
{
|
|
578
|
+
account: account as never,
|
|
579
|
+
accessKey: parameters.accessKeyAddress,
|
|
580
|
+
...(feePayer ? { feePayer: true } : {}),
|
|
581
|
+
...(parameters.keyAuthorization
|
|
582
|
+
? { keyAuthorization: parameters.keyAuthorization }
|
|
583
|
+
: {}),
|
|
584
|
+
},
|
|
585
|
+
)
|
|
578
586
|
} catch (error) {
|
|
579
|
-
if (!AccessKey.isUnavailableError(error)) throw error
|
|
587
|
+
if (typeof feePayer === 'string' || !AccessKey.isUnavailableError(error)) throw error
|
|
580
588
|
}
|
|
581
589
|
store.accessKeys.remove({
|
|
582
590
|
accessKey: parameters.accessKeyAddress,
|
|
@@ -69,6 +69,32 @@ describe('validate', () => {
|
|
|
69
69
|
`)
|
|
70
70
|
})
|
|
71
71
|
|
|
72
|
+
test('behavior: preserves access-key revocation sponsorship', () => {
|
|
73
|
+
const result = RpcRequest.validate(Schema.Request, {
|
|
74
|
+
method: 'wallet_revokeAccessKey',
|
|
75
|
+
params: [
|
|
76
|
+
{
|
|
77
|
+
accessKeyAddress: '0x2222222222222222222222222222222222222222',
|
|
78
|
+
address: '0x1111111111111111111111111111111111111111',
|
|
79
|
+
feePayer: 'https://app.example.com/fee-payer',
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
expect(result._decoded).toMatchInlineSnapshot(`
|
|
85
|
+
{
|
|
86
|
+
"method": "wallet_revokeAccessKey",
|
|
87
|
+
"params": [
|
|
88
|
+
{
|
|
89
|
+
"accessKeyAddress": "0x2222222222222222222222222222222222222222",
|
|
90
|
+
"address": "0x1111111111111111111111111111111111111111",
|
|
91
|
+
"feePayer": "https://app.example.com/fee-payer",
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
}
|
|
95
|
+
`)
|
|
96
|
+
})
|
|
97
|
+
|
|
72
98
|
test('default: validates wallet_switchEthereumChain with hex chainId', () => {
|
|
73
99
|
const result = RpcRequest.validate(Schema.Request, {
|
|
74
100
|
method: 'wallet_switchEthereumChain',
|
package/src/core/zod/rpc.ts
CHANGED
|
@@ -51,6 +51,7 @@ type KeyAuthorizationRpcDecoded = Omit<KeyAuthorization.Rpc, 'chainId' | 'expiry
|
|
|
51
51
|
address?: KeyAuthorization.Rpc['keyId'] | undefined
|
|
52
52
|
chainId: bigint
|
|
53
53
|
expiry: number | null | undefined
|
|
54
|
+
keyType: z.output<typeof keyType>
|
|
54
55
|
limits?:
|
|
55
56
|
| readonly {
|
|
56
57
|
token: KeyAuthorization.RpcTokenLimit['token']
|
|
@@ -133,7 +134,7 @@ export const keyAuthorization = z.codec(keyAuthorizationRpc, z.custom<KeyAuthori
|
|
|
133
134
|
chainId: keyAuthorization.chainId === '0x' ? 0n : Hex.toBigInt(keyAuthorization.chainId),
|
|
134
135
|
expiry: keyAuthorization.expiry == null ? null : Hex.toNumber(keyAuthorization.expiry),
|
|
135
136
|
keyId: keyAuthorization.keyId,
|
|
136
|
-
keyType: keyAuthorization.keyType,
|
|
137
|
+
keyType: z.parse(keyType, keyAuthorization.keyType),
|
|
137
138
|
limits: keyAuthorization.limits?.map(({ limit, period, token }) => ({
|
|
138
139
|
token,
|
|
139
140
|
limit: Hex.toBigInt(limit),
|
|
@@ -540,11 +541,21 @@ export namespace wallet_authorizeAccessKey_strict {
|
|
|
540
541
|
}
|
|
541
542
|
|
|
542
543
|
export namespace wallet_revokeAccessKey {
|
|
544
|
+
/** Parameters for revoking an access key. */
|
|
545
|
+
export const parameters = z.object({
|
|
546
|
+
/** Root account address. */
|
|
547
|
+
address: u.address(),
|
|
548
|
+
/** Address of the access key to revoke. */
|
|
549
|
+
accessKeyAddress: u.address(),
|
|
550
|
+
/** App-provided fee sponsorship for the revocation transaction. */
|
|
551
|
+
feePayer: z.optional(z.union([z.boolean(), z.string()])),
|
|
552
|
+
/** Signed authorization for an access key that has not been published on-chain. */
|
|
553
|
+
keyAuthorization: z.optional(keyAuthorization),
|
|
554
|
+
})
|
|
555
|
+
|
|
543
556
|
export const schema = Schema.defineItem({
|
|
544
557
|
method: z.literal('wallet_revokeAccessKey'),
|
|
545
|
-
params: z.readonly(
|
|
546
|
-
z.tuple([z.object({ address: u.address(), accessKeyAddress: u.address() })]),
|
|
547
|
-
),
|
|
558
|
+
params: z.readonly(z.tuple([parameters])),
|
|
548
559
|
returns: undefined,
|
|
549
560
|
})
|
|
550
561
|
export type Encoded = Schema.Encoded<typeof schema>
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { vi } from 'vitest'
|
|
2
|
+
import { afterEach, describe, expect, test } from 'vp/test'
|
|
3
|
+
|
|
4
|
+
const hooks = vi.hoisted(() => ({ cleanups: [] as (() => void)[] }))
|
|
5
|
+
|
|
6
|
+
vi.mock('react', () => ({
|
|
7
|
+
useCallback: (fn: unknown) => fn,
|
|
8
|
+
useEffect: (effect: () => void | (() => void)) => {
|
|
9
|
+
const cleanup = effect()
|
|
10
|
+
if (cleanup) hooks.cleanups.push(cleanup)
|
|
11
|
+
},
|
|
12
|
+
useMemo: (fn: () => unknown) => fn(),
|
|
13
|
+
useRef: (current: unknown) => ({ current }),
|
|
14
|
+
useState: (initial: unknown) => [initial, () => {}],
|
|
15
|
+
}))
|
|
16
|
+
|
|
17
|
+
import { useTheme } from './Remote.js'
|
|
18
|
+
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
hooks.cleanups.length = 0
|
|
21
|
+
vi.unstubAllGlobals()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
describe('useTheme', () => {
|
|
25
|
+
test('behavior: applies URL theme values to the document', () => {
|
|
26
|
+
const root = createRoot()
|
|
27
|
+
stubBrowser(root, '?accent=%23b9a3ff&radius=medium&scheme=dark')
|
|
28
|
+
|
|
29
|
+
useTheme()
|
|
30
|
+
|
|
31
|
+
expect(readRoot(root)).toMatchInlineSnapshot(`
|
|
32
|
+
{
|
|
33
|
+
"attributes": {
|
|
34
|
+
"data-theme": "dark",
|
|
35
|
+
"data-theme-accent": "custom",
|
|
36
|
+
"data-theme-radius": "medium",
|
|
37
|
+
},
|
|
38
|
+
"colorScheme": "dark",
|
|
39
|
+
"properties": {
|
|
40
|
+
"--theme-accent": "#b9a3ff",
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
`)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('behavior: replaces URL overrides with live theme updates', () => {
|
|
47
|
+
const root = createRoot()
|
|
48
|
+
stubBrowser(root, '?accent=purple&radius=full&scheme=dark')
|
|
49
|
+
let update: ((theme: { scheme?: string }) => void) | undefined
|
|
50
|
+
const remote = {
|
|
51
|
+
messenger: {
|
|
52
|
+
on(_topic: string, listener: typeof update) {
|
|
53
|
+
update = listener
|
|
54
|
+
return () => {}
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
}
|
|
58
|
+
useTheme(remote as never)
|
|
59
|
+
|
|
60
|
+
update?.({ scheme: 'light' })
|
|
61
|
+
|
|
62
|
+
expect(readRoot(root)).toMatchInlineSnapshot(`
|
|
63
|
+
{
|
|
64
|
+
"attributes": {
|
|
65
|
+
"data-theme": "light",
|
|
66
|
+
},
|
|
67
|
+
"colorScheme": "light",
|
|
68
|
+
"properties": {},
|
|
69
|
+
}
|
|
70
|
+
`)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test('behavior: restores the document theme when unmounted', () => {
|
|
74
|
+
const root = createRoot(
|
|
75
|
+
{
|
|
76
|
+
'data-theme': 'light',
|
|
77
|
+
'data-theme-accent': 'custom',
|
|
78
|
+
'data-theme-radius': 'small',
|
|
79
|
+
},
|
|
80
|
+
'light',
|
|
81
|
+
{ '--theme-accent': '#ff007a' },
|
|
82
|
+
)
|
|
83
|
+
stubBrowser(root, '?accent=blue&radius=full&scheme=dark')
|
|
84
|
+
useTheme()
|
|
85
|
+
|
|
86
|
+
hooks.cleanups[0]?.()
|
|
87
|
+
|
|
88
|
+
expect(readRoot(root)).toMatchInlineSnapshot(`
|
|
89
|
+
{
|
|
90
|
+
"attributes": {
|
|
91
|
+
"data-theme": "light",
|
|
92
|
+
"data-theme-accent": "custom",
|
|
93
|
+
"data-theme-radius": "small",
|
|
94
|
+
},
|
|
95
|
+
"colorScheme": "light",
|
|
96
|
+
"properties": {
|
|
97
|
+
"--theme-accent": "#ff007a",
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
`)
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
// Helpers
|
|
105
|
+
|
|
106
|
+
function stubBrowser(root: ReturnType<typeof createRoot>, search: string) {
|
|
107
|
+
vi.stubGlobal('document', { documentElement: root })
|
|
108
|
+
vi.stubGlobal('window', { location: { search } })
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function createRoot(
|
|
112
|
+
initialAttributes: Record<string, string> = {},
|
|
113
|
+
colorScheme = '',
|
|
114
|
+
initialProperties: Record<string, string> = {},
|
|
115
|
+
) {
|
|
116
|
+
const attributes = new Map(Object.entries(initialAttributes))
|
|
117
|
+
const properties = new Map(Object.entries(initialProperties))
|
|
118
|
+
return {
|
|
119
|
+
attributes,
|
|
120
|
+
getAttribute(name: string) {
|
|
121
|
+
return attributes.get(name) ?? null
|
|
122
|
+
},
|
|
123
|
+
removeAttribute(name: string) {
|
|
124
|
+
attributes.delete(name)
|
|
125
|
+
},
|
|
126
|
+
setAttribute(name: string, value: string) {
|
|
127
|
+
attributes.set(name, value)
|
|
128
|
+
},
|
|
129
|
+
style: {
|
|
130
|
+
colorScheme,
|
|
131
|
+
getPropertyValue(name: string) {
|
|
132
|
+
return properties.get(name) ?? ''
|
|
133
|
+
},
|
|
134
|
+
removeProperty(name: string) {
|
|
135
|
+
const value = properties.get(name) ?? ''
|
|
136
|
+
properties.delete(name)
|
|
137
|
+
return value
|
|
138
|
+
},
|
|
139
|
+
setProperty(name: string, value: string) {
|
|
140
|
+
properties.set(name, value)
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
properties,
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function readRoot(root: ReturnType<typeof createRoot>) {
|
|
148
|
+
return {
|
|
149
|
+
attributes: Object.fromEntries(root.attributes),
|
|
150
|
+
colorScheme: root.style.colorScheme,
|
|
151
|
+
properties: Object.fromEntries(root.properties),
|
|
152
|
+
}
|
|
153
|
+
}
|
package/src/react/Remote.ts
CHANGED
|
@@ -126,7 +126,10 @@ function applyTheme(theme: {
|
|
|
126
126
|
root.setAttribute('data-theme-accent', getAccentName(accent))
|
|
127
127
|
if (!isAccentPreset(accent)) root.style.setProperty('--theme-accent', accent)
|
|
128
128
|
}
|
|
129
|
-
if (scheme)
|
|
129
|
+
if (scheme) {
|
|
130
|
+
root.style.colorScheme = scheme
|
|
131
|
+
root.setAttribute('data-theme', scheme)
|
|
132
|
+
}
|
|
130
133
|
if (radius) root.setAttribute('data-theme-radius', radius)
|
|
131
134
|
}
|
|
132
135
|
|
|
@@ -137,11 +140,13 @@ function captureTheme(): ThemeSnapshot {
|
|
|
137
140
|
accentValue: root.style.getPropertyValue('--theme-accent'),
|
|
138
141
|
colorScheme: root.style.colorScheme,
|
|
139
142
|
radius: root.getAttribute('data-theme-radius'),
|
|
143
|
+
scheme: root.getAttribute('data-theme'),
|
|
140
144
|
}
|
|
141
145
|
}
|
|
142
146
|
|
|
143
147
|
function restoreTheme(snapshot: ThemeSnapshot) {
|
|
144
148
|
const root = document.documentElement
|
|
149
|
+
restoreAttribute(root, 'data-theme', snapshot.scheme)
|
|
145
150
|
restoreAttribute(root, 'data-theme-accent', snapshot.accentPreset)
|
|
146
151
|
restoreAttribute(root, 'data-theme-radius', snapshot.radius)
|
|
147
152
|
if (snapshot.accentValue) root.style.setProperty('--theme-accent', snapshot.accentValue)
|
|
@@ -175,6 +180,7 @@ type ThemeSnapshot = {
|
|
|
175
180
|
accentValue: string
|
|
176
181
|
colorScheme: string
|
|
177
182
|
radius: string | null
|
|
183
|
+
scheme: string | null
|
|
178
184
|
}
|
|
179
185
|
|
|
180
186
|
export declare namespace useEnsureVisibility {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Base64, Hex } from 'ox'
|
|
2
|
-
import { KeyAuthorization } from 'ox/tempo'
|
|
2
|
+
import { KeyAuthorization, SignatureEnvelope } from 'ox/tempo'
|
|
3
3
|
import { createClient, custom, encodeErrorResult, encodeFunctionResult } from 'viem'
|
|
4
4
|
import { Abis, Account as TempoAccount } from 'viem/tempo'
|
|
5
5
|
import { describe, expect, test } from 'vp/test'
|
|
@@ -89,6 +89,7 @@ async function authorize(
|
|
|
89
89
|
code,
|
|
90
90
|
keyAuthorization: z.decode(CliAuth.keyAuthorization, {
|
|
91
91
|
...keyAuthorization,
|
|
92
|
+
keyType: key.keyType,
|
|
92
93
|
address: keyAuthorization.keyId,
|
|
93
94
|
}),
|
|
94
95
|
} satisfies z.output<typeof CliAuth.authorizeRequest>
|
|
@@ -126,6 +127,7 @@ async function authorizeWebAuthn(
|
|
|
126
127
|
code,
|
|
127
128
|
keyAuthorization: z.decode(CliAuth.keyAuthorization, {
|
|
128
129
|
...keyAuthorization,
|
|
130
|
+
keyType: key.keyType,
|
|
129
131
|
address: keyAuthorization.keyId,
|
|
130
132
|
}),
|
|
131
133
|
} satisfies z.output<typeof CliAuth.authorizeRequest>
|
|
@@ -1199,7 +1201,7 @@ describe('poll', () => {
|
|
|
1199
1201
|
keyAuthorization: {
|
|
1200
1202
|
...first.keyAuthorization,
|
|
1201
1203
|
signature: {
|
|
1202
|
-
type: first.keyAuthorization.signature.type,
|
|
1204
|
+
type: SignatureEnvelope.fromRpc(first.keyAuthorization.signature).type,
|
|
1203
1205
|
},
|
|
1204
1206
|
},
|
|
1205
1207
|
}
|
|
@@ -1727,7 +1729,7 @@ describe('authorize', () => {
|
|
|
1727
1729
|
? {
|
|
1728
1730
|
...polled.keyAuthorization,
|
|
1729
1731
|
signature: {
|
|
1730
|
-
type: polled.keyAuthorization.signature.type,
|
|
1732
|
+
type: SignatureEnvelope.fromRpc(polled.keyAuthorization.signature).type,
|
|
1731
1733
|
},
|
|
1732
1734
|
}
|
|
1733
1735
|
: undefined
|
package/src/server/CliAuth.ts
CHANGED
|
@@ -765,11 +765,12 @@ export function from(options: from.Options = {}): CliAuth {
|
|
|
765
765
|
})
|
|
766
766
|
|
|
767
767
|
const client = options.client ?? cache.get(current.chainId)
|
|
768
|
+
const signature = SignatureEnvelope.fromRpc(actual.signature)
|
|
768
769
|
const valid = await verifyHash(client, {
|
|
769
770
|
address: options.request.accountAddress,
|
|
770
771
|
hash: TempoKeyAuthorization.getSignPayload(signed),
|
|
771
|
-
signature: SignatureEnvelope.serialize(
|
|
772
|
-
magic:
|
|
772
|
+
signature: SignatureEnvelope.serialize(signature, {
|
|
773
|
+
magic: signature.type === 'webAuthn',
|
|
773
774
|
}),
|
|
774
775
|
})
|
|
775
776
|
if (!valid) throw new Error('Key authorization signature is invalid.')
|
|
@@ -1258,11 +1259,12 @@ async function verifyKeyAuthorizationSignature(options: {
|
|
|
1258
1259
|
...(actual.limits ? { limits: actual.limits } : {}),
|
|
1259
1260
|
type: actual.keyType,
|
|
1260
1261
|
})
|
|
1262
|
+
const signature = SignatureEnvelope.fromRpc(actual.signature)
|
|
1261
1263
|
const valid = await verifyHash(options.client, {
|
|
1262
1264
|
address: options.account,
|
|
1263
1265
|
hash: TempoKeyAuthorization.getSignPayload(unsigned),
|
|
1264
|
-
signature: SignatureEnvelope.serialize(
|
|
1265
|
-
magic:
|
|
1266
|
+
signature: SignatureEnvelope.serialize(signature, {
|
|
1267
|
+
magic: signature.type === 'webAuthn',
|
|
1266
1268
|
}),
|
|
1267
1269
|
})
|
|
1268
1270
|
if (!valid) throw new Error('Key authorization signature is invalid.')
|
|
@@ -26,7 +26,6 @@ import { type Handler, from } from '../../Handler.js'
|
|
|
26
26
|
import * as Kv from '../../Kv.js'
|
|
27
27
|
import { cached } from '../kv.js'
|
|
28
28
|
import * as Tokenlist from '../tokenlist.js'
|
|
29
|
-
import * as Multisig from './multisig.js'
|
|
30
29
|
import * as Sponsorship from './sponsorship.js'
|
|
31
30
|
import * as Utils from './utils.js'
|
|
32
31
|
|
|
@@ -84,7 +83,6 @@ export function relay(options: relay.Options = {}): Handler {
|
|
|
84
83
|
...rest
|
|
85
84
|
} = options
|
|
86
85
|
const feePayerOptions = options.feePayer
|
|
87
|
-
const multisigOptions = options.multisig
|
|
88
86
|
|
|
89
87
|
// Resolves the verified tokenlist for `chainId`, sharing the KV cache with
|
|
90
88
|
// `Handler.exchange` so a single `kv: Kv.cloudflare(env.KV)` covers both.
|
|
@@ -519,33 +517,6 @@ export function relay(options: relay.Options = {}): Handler {
|
|
|
519
517
|
case 'eth_sendRawTransactionSync': {
|
|
520
518
|
try {
|
|
521
519
|
const serialized = params[0]
|
|
522
|
-
if (
|
|
523
|
-
multisigOptions &&
|
|
524
|
-
(request.method === 'eth_sendRawTransaction' ||
|
|
525
|
-
request.method === 'eth_sendRawTransactionSync') &&
|
|
526
|
-
typeof serialized === 'string' &&
|
|
527
|
-
Multisig.isMultisigTransaction(serialized as Hex.Hex)
|
|
528
|
-
) {
|
|
529
|
-
const result = await Multisig.handleRawTransaction({
|
|
530
|
-
claimTtl: multisigOptions.claimTtl,
|
|
531
|
-
finalize: multisigOptions.finalize,
|
|
532
|
-
getClient,
|
|
533
|
-
method: request.method,
|
|
534
|
-
request: { params: 'params' in request ? request.params : undefined },
|
|
535
|
-
resolveConfig: multisigOptions.resolveConfig,
|
|
536
|
-
sponsor: feePayerOptions
|
|
537
|
-
? {
|
|
538
|
-
account: feePayerOptions.account,
|
|
539
|
-
feeToken: feePayerOptions.feeToken,
|
|
540
|
-
resolveFeeToken: async (chainId) => (await getTokens(chainId))[0],
|
|
541
|
-
validate: feePayerOptions.validate,
|
|
542
|
-
}
|
|
543
|
-
: undefined,
|
|
544
|
-
store: multisigOptions.store,
|
|
545
|
-
})
|
|
546
|
-
return RpcResponse.from({ result } as never, { request } as never)
|
|
547
|
-
}
|
|
548
|
-
|
|
549
520
|
if (!feePayerOptions) {
|
|
550
521
|
// eth_signRawTransaction is a signing method that only the
|
|
551
522
|
// relay can fulfill — forwarding it to the RPC node returns
|
|
@@ -590,27 +561,6 @@ export function relay(options: relay.Options = {}): Handler {
|
|
|
590
561
|
}
|
|
591
562
|
}
|
|
592
563
|
|
|
593
|
-
case 'eth_getTransactionByHash':
|
|
594
|
-
case 'eth_getTransactionReceipt': {
|
|
595
|
-
try {
|
|
596
|
-
if (multisigOptions) {
|
|
597
|
-
const aliased = await Multisig.handleGetTransaction({
|
|
598
|
-
getClient,
|
|
599
|
-
method: request.method,
|
|
600
|
-
request: { params: 'params' in request ? request.params : undefined },
|
|
601
|
-
store: multisigOptions.store,
|
|
602
|
-
})
|
|
603
|
-
if (aliased)
|
|
604
|
-
return RpcResponse.from({ result: aliased.result } as never, { request } as never)
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
const result = await client.request(request as never)
|
|
608
|
-
return RpcResponse.from({ result }, { request })
|
|
609
|
-
} catch (error) {
|
|
610
|
-
return Utils.rpcErrorJson(request, error)
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
|
|
614
564
|
default: {
|
|
615
565
|
try {
|
|
616
566
|
const result = await client.request(request as never)
|
|
@@ -696,12 +646,6 @@ export namespace relay {
|
|
|
696
646
|
url?: string | undefined
|
|
697
647
|
}
|
|
698
648
|
| undefined
|
|
699
|
-
/**
|
|
700
|
-
* Native multisig configuration. When provided, the relay collects owner
|
|
701
|
-
* approvals from multisig raw transaction submissions and broadcasts once
|
|
702
|
-
* collected owner weight meets the configured threshold.
|
|
703
|
-
*/
|
|
704
|
-
multisig?: Multisig.Options | undefined
|
|
705
649
|
/**
|
|
706
650
|
* Relay features.
|
|
707
651
|
*
|
|
@@ -121,8 +121,7 @@ export async function handleRawTransaction(options: handleRawTransaction.Options
|
|
|
121
121
|
})
|
|
122
122
|
|
|
123
123
|
const transaction = Transaction.deserialize(serialized)
|
|
124
|
-
|
|
125
|
-
const sender = transaction.from ?? options.sender
|
|
124
|
+
const sender = transaction.from
|
|
126
125
|
|
|
127
126
|
// Sponsorship only applies after sender has signed original transaction.
|
|
128
127
|
if (!transaction.signature || !sender)
|
|
@@ -178,8 +177,6 @@ export declare namespace handleRawTransaction {
|
|
|
178
177
|
method: 'eth_signRawTransaction' | 'eth_sendRawTransaction' | 'eth_sendRawTransactionSync'
|
|
179
178
|
/** Incoming JSON-RPC request. */
|
|
180
179
|
request: { params?: readonly unknown[] | undefined }
|
|
181
|
-
/** Sender address to use if it cannot be recovered from the raw envelope. */
|
|
182
|
-
sender?: Address | undefined
|
|
183
180
|
/** Optional sponsorship approval callback. */
|
|
184
181
|
validate?: ((request: Transaction.TransactionRequest) => boolean | Promise<boolean>) | undefined
|
|
185
182
|
}
|