Skip to content

Commit bcff875

Browse files
committed
feat: add sign actions for swaps typedData
1 parent 22cca88 commit bcff875

File tree

6 files changed

+103
-78
lines changed

6 files changed

+103
-78
lines changed

packages/client/src/ethers.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import {
44
ValidationError,
55
} from '@aave/core-next';
66
import type {
7+
CancelSwapTypedData,
78
InsufficientBalanceError,
89
PermitTypedDataResponse,
10+
SwapByIntentTypedData,
911
TransactionRequest,
1012
} from '@aave/graphql-next';
1113
import {
@@ -20,6 +22,7 @@ import type { Signer, TransactionResponse } from 'ethers';
2022
import type {
2123
ExecutionPlanHandler,
2224
PermitHandler,
25+
SwapSignatureHandler,
2326
TransactionExecutionResult,
2427
} from './types';
2528

@@ -100,3 +103,19 @@ export function signERC20PermitWith(signer: Signer): PermitHandler {
100103
}));
101104
};
102105
}
106+
107+
/**
108+
* Signs swap typed data using the provided ethers signer.
109+
*/
110+
export function signSwapTypedDataWith(signer: Signer): SwapSignatureHandler {
111+
return (result: SwapByIntentTypedData | CancelSwapTypedData) => {
112+
const message = JSON.parse(result.message);
113+
return ResultAsync.fromPromise(
114+
signer.signTypedData(result.domain, result.types, message),
115+
(err) => SigningError.from(err),
116+
).map((signature) => ({
117+
deadline: message.deadline,
118+
value: signatureFrom(signature),
119+
}));
120+
};
121+
}

packages/client/src/privy.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import {
44
ValidationError,
55
} from '@aave/core-next';
66
import type {
7+
CancelSwapTypedData,
78
InsufficientBalanceError,
89
PermitTypedDataResponse,
10+
SwapByIntentTypedData,
911
TransactionRequest,
1012
} from '@aave/graphql-next';
1113
import {
@@ -22,6 +24,7 @@ import { waitForTransactionReceipt } from 'viem/actions';
2224
import type {
2325
ExecutionPlanHandler,
2426
PermitHandler,
27+
SwapSignatureHandler,
2528
TransactionExecutionResult,
2629
} from './types';
2730
import { supportedChains, transactionError } from './viem';
@@ -135,3 +138,30 @@ export function signERC20PermitWith(
135138
}));
136139
};
137140
}
141+
142+
/**
143+
* Signs swap typed data using the provided Privy client.
144+
*/
145+
export function signSwapTypedDataWith(
146+
privy: PrivyClient,
147+
walletId: string,
148+
): SwapSignatureHandler {
149+
return (result: SwapByIntentTypedData | CancelSwapTypedData) => {
150+
const message = JSON.parse(result.message);
151+
return ResultAsync.fromPromise(
152+
privy.walletApi.ethereum.signTypedData({
153+
walletId,
154+
typedData: {
155+
domain: result.domain,
156+
types: result.types,
157+
message,
158+
primaryType: result.primaryType,
159+
},
160+
}),
161+
(err) => SigningError.from(err),
162+
).map((response) => ({
163+
deadline: message.deadline,
164+
value: signatureFrom(response.signature),
165+
}));
166+
};
167+
}

packages/client/src/thirdweb.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import {
44
ValidationError,
55
} from '@aave/core-next';
66
import type {
7+
CancelSwapTypedData,
78
InsufficientBalanceError,
89
PermitTypedDataResponse,
10+
SwapByIntentTypedData,
911
TransactionRequest,
1012
} from '@aave/graphql-next';
1113
import {
@@ -26,6 +28,7 @@ import {
2628
import type {
2729
ExecutionPlanHandler,
2830
PermitHandler,
31+
SwapSignatureHandler,
2932
TransactionExecutionResult,
3033
} from './types';
3134

@@ -139,3 +142,39 @@ export function signERC20PermitWith(client: ThirdwebClient): PermitHandler {
139142
}));
140143
};
141144
}
145+
146+
/**
147+
* Signs swap typed data using the provided Thirdweb client.
148+
*/
149+
export function signSwapTypedDataWith(
150+
client: ThirdwebClient,
151+
): SwapSignatureHandler {
152+
return (result: SwapByIntentTypedData | CancelSwapTypedData) => {
153+
const message = JSON.parse(result.message);
154+
155+
const signTypedDataPromise = async (): Promise<Signature> => {
156+
const wallet = Engine.serverWallet({
157+
client,
158+
chain: defineChain({ id: result.domain.chainId }),
159+
address: message.user,
160+
});
161+
162+
const signature = await wallet.signTypedData({
163+
// silence the rest of the type inference
164+
types: result.types as Record<string, unknown>,
165+
domain: result.domain,
166+
primaryType: result.primaryType,
167+
message,
168+
});
169+
170+
return signatureFrom(signature);
171+
};
172+
173+
return ResultAsync.fromPromise(signTypedDataPromise(), (err) =>
174+
SigningError.from(err),
175+
).map((value) => ({
176+
deadline: message.deadline,
177+
value,
178+
}));
179+
};
180+
}

packages/client/src/types.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ export type PermitHandler = (
4444
result: PermitTypedDataResponse,
4545
) => ResultAsync<ERC712Signature, SigningError>;
4646

47-
export type SwapByIntentHandler = (
48-
result: SwapByIntentTypedData,
49-
) => ResultAsync<ERC712Signature, SigningError>;
50-
51-
export type SwapCancelHandler = (
52-
result: CancelSwapTypedData,
47+
export type SwapSignatureHandler = (
48+
result: CancelSwapTypedData | SwapByIntentTypedData,
5349
) => ResultAsync<ERC712Signature, SigningError>;

packages/client/src/viem.ts

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ import { mainnet } from 'viem/chains';
4141
import type {
4242
ExecutionPlanHandler,
4343
PermitHandler,
44-
SwapByIntentHandler,
45-
SwapCancelHandler,
44+
SwapSignatureHandler,
4645
TransactionExecutionResult,
4746
} from './types';
4847

@@ -179,37 +178,12 @@ export function signERC20PermitWith(walletClient: WalletClient): PermitHandler {
179178
}
180179

181180
/**
182-
* Signs a swap by intent using the provided wallet client.
181+
* Signs swap typed data using the provided wallet client.
183182
*/
184-
export function signSwapByIntentWith(
183+
export function signSwapTypedDataWith(
185184
walletClient: WalletClient,
186-
): SwapByIntentHandler {
187-
return (result: SwapByIntentTypedData) => {
188-
invariant(walletClient.account, 'Wallet account is required');
189-
190-
return ResultAsync.fromPromise(
191-
signTypedData(walletClient, {
192-
account: walletClient.account,
193-
domain: result.domain as TypedDataDomain,
194-
types: result.types as TypedData,
195-
primaryType: result.primaryType,
196-
message: JSON.parse(result.message),
197-
}),
198-
(err) => SigningError.from(err),
199-
).map((hex) => ({
200-
deadline: JSON.parse(result.message).deadline,
201-
value: signatureFrom(hex),
202-
}));
203-
};
204-
}
205-
206-
/**
207-
* Signs a swap cancellation using the provided wallet client.
208-
*/
209-
export function signSwapCancelWith(
210-
walletClient: WalletClient,
211-
): SwapCancelHandler {
212-
return (result: CancelSwapTypedData) => {
185+
): SwapSignatureHandler {
186+
return (result: SwapByIntentTypedData | CancelSwapTypedData) => {
213187
invariant(walletClient.account, 'Wallet account is required');
214188

215189
return ResultAsync.fromPromise(

packages/react/src/viem.ts

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import { permitTypedData } from '@aave/client-next/actions';
33
import {
44
sendTransactionAndWait,
55
signERC20PermitWith,
6-
signSwapByIntentWith,
7-
signSwapCancelWith,
6+
signSwapTypedDataWith,
87
} from '@aave/client-next/viem';
98
import type {
109
CancelSwapTypedData,
@@ -94,62 +93,30 @@ export function useERC20Permit(
9493
export type SignSwapError = SigningError | UnexpectedError;
9594

9695
/**
97-
* A hook that provides a way to sign swap by intent using a viem WalletClient instance.
96+
* A hook that provides a way to sign swap typed data using a viem WalletClient instance.
9897
*
9998
* ```ts
10099
* const { data: wallet } = useWalletClient(); // wagmi hook
101-
* const [signSwapByIntent, { loading, error, data }] = useSignSwapByIntentWith(wallet);
100+
* const [signSwapTypedData, { loading, error, data }] = useSignSwapTypedDataWith(wallet);
102101
*
103102
* const run = async () => {
104-
* const result = await signSwapByIntent(swapByIntentTypedData);
103+
* const result = await signSwapTypedData(swapTypedData);
105104
*
106105
* if (result.isErr()) {
107106
* console.error(result.error);
108107
* return;
109108
* }
110109
*
111-
* console.log('Swap by intent signed:', result.value);
110+
* console.log('Swap typed data signed:', result.value);
112111
* };
113112
* ```
114113
*/
115-
export function useSignSwapByIntentWith(
114+
export function useSignSwapTypedDataWith(
116115
walletClient: WalletClient | undefined,
117116
): UseAsyncTask<SwapByIntentTypedData, ERC712Signature, SignSwapError> {
118117
return useAsyncTask((typedData: SwapByIntentTypedData) => {
119-
invariant(walletClient, 'Expected a WalletClient to sign swap by intent');
118+
invariant(walletClient, 'Expected a WalletClient to sign swap typed data');
120119

121-
return signSwapByIntentWith(walletClient)(typedData);
122-
});
123-
}
124-
125-
/**
126-
* A hook that provides a way to sign swap cancellation using a viem WalletClient instance.
127-
*
128-
* ```ts
129-
* const { data: wallet } = useWalletClient(); // wagmi hook
130-
* const [signSwapCancel, { loading, error, data }] = useSignSwapCancelWith(wallet);
131-
*
132-
* const run = async () => {
133-
* const result = await signSwapCancel(cancelSwapTypedData);
134-
*
135-
* if (result.isErr()) {
136-
* console.error(result.error);
137-
* return;
138-
* }
139-
*
140-
* console.log('Swap cancellation signed:', result.value);
141-
* };
142-
* ```
143-
*/
144-
export function useSignSwapCancelWith(
145-
walletClient: WalletClient | undefined,
146-
): UseAsyncTask<CancelSwapTypedData, ERC712Signature, SignSwapError> {
147-
return useAsyncTask((typedData: CancelSwapTypedData) => {
148-
invariant(
149-
walletClient,
150-
'Expected a WalletClient to sign swap cancellation',
151-
);
152-
153-
return signSwapCancelWith(walletClient)(typedData);
120+
return signSwapTypedDataWith(walletClient)(typedData);
154121
});
155122
}

0 commit comments

Comments
 (0)