Skip to content

Commit a2eca4e

Browse files
authored
authorization list support on send-transaction (#837)
* authorization list support on send-transaction * fix: clean up unused imports in transaction overrides utility and update yarn.lock for dependency management
1 parent 8f59c2e commit a2eca4e

File tree

6 files changed

+63
-4
lines changed

6 files changed

+63
-4
lines changed

src/server/middleware/error.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ export const badChainError = (chain: string | number): CustomError =>
4242
"INVALID_CHAIN",
4343
);
4444

45+
export const badBigIntError = (variableName: string): CustomError =>
46+
createCustomError(
47+
`Invalid BigInt: ${variableName}`,
48+
StatusCodes.BAD_REQUEST,
49+
"INVALID_BIGINT",
50+
);
51+
4552
const flipObject = (data: object) =>
4653
Object.fromEntries(Object.entries(data).map(([key, value]) => [value, key]));
4754

src/server/routes/backend-wallet/send-transaction.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import {
1717
} from "../../schemas/wallet";
1818
import { getChainIdFromChain } from "../../utils/chain";
1919
import { parseTransactionOverrides } from "../../utils/transaction-overrides";
20+
import {
21+
authorizationListSchema,
22+
toParsedAuthorization,
23+
} from "../../schemas/transaction/authorization";
2024

2125
const requestBodySchema = Type.Object({
2226
toAddress: Type.Optional(AddressSchema),
@@ -26,6 +30,7 @@ const requestBodySchema = Type.Object({
2630
value: Type.String({
2731
examples: ["10000000"],
2832
}),
33+
authorizationList: authorizationListSchema,
2934
...txOverridesSchema.properties,
3035
});
3136

@@ -65,7 +70,8 @@ export async function sendTransaction(fastify: FastifyInstance) {
6570
},
6671
handler: async (request, reply) => {
6772
const { chain } = request.params;
68-
const { toAddress, data, value, txOverrides } = request.body;
73+
const { toAddress, data, value, txOverrides, authorizationList } =
74+
request.body;
6975
const { simulateTx } = request.query;
7076
const {
7177
"x-backend-wallet-address": fromAddress,
@@ -110,6 +116,7 @@ export async function sendTransaction(fastify: FastifyInstance) {
110116
data: data as Hex,
111117
transactionMode: transactionMode,
112118
value: BigInt(value),
119+
authorizationList: authorizationList?.map(toParsedAuthorization),
113120
...parseTransactionOverrides(txOverrides),
114121
},
115122
shouldSimulate: simulateTx,
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { type Static, Type } from "@sinclair/typebox";
2+
import { AddressSchema } from "../address";
3+
import { requiredAddress } from "../wallet";
4+
import { requiredBigInt } from "../../../shared/utils/primitive-types";
5+
6+
export const authorizationSchema = Type.Object({
7+
address: AddressSchema,
8+
chainId: Type.Integer(),
9+
nonce: Type.String(),
10+
r: Type.String(),
11+
s: Type.String(),
12+
yParity: Type.Number(),
13+
});
14+
15+
export const authorizationListSchema = Type.Optional(
16+
Type.Array(authorizationSchema),
17+
);
18+
19+
export const toParsedAuthorization = (
20+
authorization: Static<typeof authorizationSchema>,
21+
) => {
22+
return {
23+
address: requiredAddress(authorization.address, "[Authorization List]"),
24+
chainId: authorization.chainId,
25+
nonce: requiredBigInt(authorization.nonce, "[Authorization List] -> nonce"),
26+
r: requiredBigInt(authorization.r, "[Authorization List] -> r"),
27+
s: requiredBigInt(authorization.s, "[Authorization List] -> s"),
28+
yParity: authorization.yParity,
29+
};
30+
};

src/server/utils/transaction-overrides.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { Static } from "@sinclair/typebox";
22
import { maybeBigInt } from "../../shared/utils/primitive-types";
3-
import type { InsertedTransaction } from "../../shared/utils/transaction/types";
43
import type {
54
txOverridesSchema,
65
txOverridesWithValueSchema,
@@ -10,7 +9,7 @@ export const parseTransactionOverrides = (
109
overrides:
1110
| Static<typeof txOverridesSchema>["txOverrides"]
1211
| Static<typeof txOverridesWithValueSchema>["txOverrides"],
13-
): Partial<InsertedTransaction> => {
12+
) => {
1413
if (!overrides) {
1514
return {};
1615
}

src/shared/utils/primitive-types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
import type { Address } from "thirdweb";
22
import { checksumAddress } from "thirdweb/utils";
3+
import { badBigIntError } from "../../server/middleware/error";
34

45
export const maybeBigInt = (val?: string) => (val ? BigInt(val) : undefined);
56
export const maybeInt = (val?: string) =>
67
val ? Number.parseInt(val) : undefined;
78

9+
export function requiredBigInt(val: string, variableName: string) {
10+
try {
11+
return BigInt(val);
12+
} catch {
13+
throw badBigIntError(variableName);
14+
}
15+
}
16+
817
// These overloads hint TS at the response type (ex: Address if `val` is Address).
918
export function normalizeAddress(val: Address): Address;
1019
export function normalizeAddress(val?: Address): Address | undefined;

src/shared/utils/transaction/types.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import type { Address, Hex, toSerializableTransaction } from "thirdweb";
1+
import {
2+
signAuthorization,
3+
SignedAuthorization,
4+
type Address,
5+
type Hex,
6+
type toSerializableTransaction,
7+
} from "thirdweb";
28
import type { TransactionType } from "viem";
39

410
// TODO: Replace with thirdweb SDK exported type when available.
@@ -30,6 +36,7 @@ export type InsertedTransaction = {
3036
value?: bigint;
3137

3238
data?: Hex;
39+
authorizationList?: SignedAuthorization[];
3340
functionName?: string;
3441
functionArgs?: unknown[];
3542

0 commit comments

Comments
 (0)