@gelatocloud/gasless 0.0.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/_dist/account/actions/getFeeQuote.d.ts +11 -0
- package/_dist/account/actions/getFeeQuote.d.ts.map +1 -0
- package/_dist/account/actions/getFeeQuote.js +21 -0
- package/_dist/account/actions/getFeeQuote.js.map +1 -0
- package/_dist/account/actions/index.d.ts +4 -0
- package/_dist/account/actions/index.d.ts.map +1 -0
- package/_dist/account/actions/index.js +20 -0
- package/_dist/account/actions/index.js.map +1 -0
- package/_dist/account/actions/sendTransaction.d.ts +20 -0
- package/_dist/account/actions/sendTransaction.d.ts.map +1 -0
- package/_dist/account/actions/sendTransaction.js +33 -0
- package/_dist/account/actions/sendTransaction.js.map +1 -0
- package/_dist/account/actions/sendTransactionSync.d.ts +9 -0
- package/_dist/account/actions/sendTransactionSync.d.ts.map +1 -0
- package/_dist/account/actions/sendTransactionSync.js +34 -0
- package/_dist/account/actions/sendTransactionSync.js.map +1 -0
- package/_dist/account/adapters/gelato/abi.d.ts +39 -0
- package/_dist/account/adapters/gelato/abi.d.ts.map +1 -0
- package/_dist/account/adapters/gelato/abi.js +13 -0
- package/_dist/account/adapters/gelato/abi.js.map +1 -0
- package/_dist/account/adapters/gelato/constants.d.ts +7 -0
- package/_dist/account/adapters/gelato/constants.d.ts.map +1 -0
- package/_dist/account/adapters/gelato/constants.js +9 -0
- package/_dist/account/adapters/gelato/constants.js.map +1 -0
- package/_dist/account/adapters/gelato/index.d.ts +10 -0
- package/_dist/account/adapters/gelato/index.d.ts.map +1 -0
- package/_dist/account/adapters/gelato/index.js +160 -0
- package/_dist/account/adapters/gelato/index.js.map +1 -0
- package/_dist/account/adapters/index.d.ts +2 -0
- package/_dist/account/adapters/index.d.ts.map +1 -0
- package/_dist/account/adapters/index.js +18 -0
- package/_dist/account/adapters/index.js.map +1 -0
- package/_dist/account/adapters/types/index.d.ts +22 -0
- package/_dist/account/adapters/types/index.d.ts.map +1 -0
- package/_dist/account/adapters/types/index.js +3 -0
- package/_dist/account/adapters/types/index.js.map +1 -0
- package/_dist/account/index.d.ts +17 -0
- package/_dist/account/index.d.ts.map +1 -0
- package/_dist/account/index.js +41 -0
- package/_dist/account/index.js.map +1 -0
- package/_dist/account/utils/delegation.d.ts +4 -0
- package/_dist/account/utils/delegation.d.ts.map +1 -0
- package/_dist/account/utils/delegation.js +12 -0
- package/_dist/account/utils/delegation.js.map +1 -0
- package/_dist/account/utils/estimation.d.ts +3 -0
- package/_dist/account/utils/estimation.d.ts.map +1 -0
- package/_dist/account/utils/estimation.js +19 -0
- package/_dist/account/utils/estimation.js.map +1 -0
- package/_dist/account/utils/index.d.ts +3 -0
- package/_dist/account/utils/index.d.ts.map +1 -0
- package/_dist/account/utils/index.js +19 -0
- package/_dist/account/utils/index.js.map +1 -0
- package/_dist/bundler/actions/estimateUserOperationGas.d.ts +6 -0
- package/_dist/bundler/actions/estimateUserOperationGas.d.ts.map +1 -0
- package/_dist/bundler/actions/estimateUserOperationGas.js +43 -0
- package/_dist/bundler/actions/estimateUserOperationGas.js.map +1 -0
- package/_dist/bundler/actions/getUserOperationGasPrice.d.ts +5 -0
- package/_dist/bundler/actions/getUserOperationGasPrice.d.ts.map +1 -0
- package/_dist/bundler/actions/getUserOperationGasPrice.js +20 -0
- package/_dist/bundler/actions/getUserOperationGasPrice.js.map +1 -0
- package/_dist/bundler/actions/getUserOperationQuote.d.ts +13 -0
- package/_dist/bundler/actions/getUserOperationQuote.d.ts.map +1 -0
- package/_dist/bundler/actions/getUserOperationQuote.js +50 -0
- package/_dist/bundler/actions/getUserOperationQuote.js.map +1 -0
- package/_dist/bundler/actions/index.d.ts +7 -0
- package/_dist/bundler/actions/index.d.ts.map +1 -0
- package/_dist/bundler/actions/index.js +23 -0
- package/_dist/bundler/actions/index.js.map +1 -0
- package/_dist/bundler/actions/prepareUserOperation.d.ts +6 -0
- package/_dist/bundler/actions/prepareUserOperation.d.ts.map +1 -0
- package/_dist/bundler/actions/prepareUserOperation.js +340 -0
- package/_dist/bundler/actions/prepareUserOperation.js.map +1 -0
- package/_dist/bundler/actions/sendUserOperation.d.ts +6 -0
- package/_dist/bundler/actions/sendUserOperation.d.ts.map +1 -0
- package/_dist/bundler/actions/sendUserOperation.js +41 -0
- package/_dist/bundler/actions/sendUserOperation.js.map +1 -0
- package/_dist/bundler/actions/sendUserOperationSync.d.ts +9 -0
- package/_dist/bundler/actions/sendUserOperationSync.d.ts.map +1 -0
- package/_dist/bundler/actions/sendUserOperationSync.js +42 -0
- package/_dist/bundler/actions/sendUserOperationSync.js.map +1 -0
- package/_dist/bundler/index.d.ts +18 -0
- package/_dist/bundler/index.d.ts.map +1 -0
- package/_dist/bundler/index.js +61 -0
- package/_dist/bundler/index.js.map +1 -0
- package/_dist/index.d.ts +5 -0
- package/_dist/index.d.ts.map +1 -0
- package/_dist/index.js +21 -0
- package/_dist/index.js.map +1 -0
- package/_dist/relayer/constants/index.d.ts +3 -0
- package/_dist/relayer/constants/index.d.ts.map +1 -0
- package/_dist/relayer/constants/index.js +6 -0
- package/_dist/relayer/constants/index.js.map +1 -0
- package/_dist/relayer/evm/actions/getCapabilities.d.ts +21 -0
- package/_dist/relayer/evm/actions/getCapabilities.d.ts.map +1 -0
- package/_dist/relayer/evm/actions/getCapabilities.js +19 -0
- package/_dist/relayer/evm/actions/getCapabilities.js.map +1 -0
- package/_dist/relayer/evm/actions/getFeeData.d.ts +21 -0
- package/_dist/relayer/evm/actions/getFeeData.d.ts.map +1 -0
- package/_dist/relayer/evm/actions/getFeeData.js +26 -0
- package/_dist/relayer/evm/actions/getFeeData.js.map +1 -0
- package/_dist/relayer/evm/actions/getFeeQuote.d.ts +22 -0
- package/_dist/relayer/evm/actions/getFeeQuote.d.ts.map +1 -0
- package/_dist/relayer/evm/actions/getFeeQuote.js +27 -0
- package/_dist/relayer/evm/actions/getFeeQuote.js.map +1 -0
- package/_dist/relayer/evm/actions/getStatus.d.ts +81 -0
- package/_dist/relayer/evm/actions/getStatus.d.ts.map +1 -0
- package/_dist/relayer/evm/actions/getStatus.js +72 -0
- package/_dist/relayer/evm/actions/getStatus.js.map +1 -0
- package/_dist/relayer/evm/actions/index.d.ts +8 -0
- package/_dist/relayer/evm/actions/index.d.ts.map +1 -0
- package/_dist/relayer/evm/actions/index.js +24 -0
- package/_dist/relayer/evm/actions/index.js.map +1 -0
- package/_dist/relayer/evm/actions/sendTransaction.d.ts +12 -0
- package/_dist/relayer/evm/actions/sendTransaction.d.ts.map +1 -0
- package/_dist/relayer/evm/actions/sendTransaction.js +22 -0
- package/_dist/relayer/evm/actions/sendTransaction.js.map +1 -0
- package/_dist/relayer/evm/actions/sendTransactionSync.d.ts +8 -0
- package/_dist/relayer/evm/actions/sendTransactionSync.d.ts.map +1 -0
- package/_dist/relayer/evm/actions/sendTransactionSync.js +23 -0
- package/_dist/relayer/evm/actions/sendTransactionSync.js.map +1 -0
- package/_dist/relayer/evm/actions/waitForStatus.d.ts +4 -0
- package/_dist/relayer/evm/actions/waitForStatus.d.ts.map +1 -0
- package/_dist/relayer/evm/actions/waitForStatus.js +17 -0
- package/_dist/relayer/evm/actions/waitForStatus.js.map +1 -0
- package/_dist/relayer/evm/index.d.ts +18 -0
- package/_dist/relayer/evm/index.d.ts.map +1 -0
- package/_dist/relayer/evm/index.js +46 -0
- package/_dist/relayer/evm/index.js.map +1 -0
- package/_dist/relayer/index.d.ts +2 -0
- package/_dist/relayer/index.d.ts.map +1 -0
- package/_dist/relayer/index.js +18 -0
- package/_dist/relayer/index.js.map +1 -0
- package/_dist/tsconfig.build.tsbuildinfo +1 -0
- package/_dist/types/error.d.ts +14 -0
- package/_dist/types/error.d.ts.map +1 -0
- package/_dist/types/error.js +27 -0
- package/_dist/types/error.js.map +1 -0
- package/_dist/types/index.d.ts +4 -0
- package/_dist/types/index.d.ts.map +1 -0
- package/_dist/types/index.js +20 -0
- package/_dist/types/index.js.map +1 -0
- package/_dist/types/payment.d.ts +17 -0
- package/_dist/types/payment.d.ts.map +1 -0
- package/_dist/types/payment.js +16 -0
- package/_dist/types/payment.js.map +1 -0
- package/_dist/types/schema.d.ts +10 -0
- package/_dist/types/schema.d.ts.map +1 -0
- package/_dist/types/schema.js +25 -0
- package/_dist/types/schema.js.map +1 -0
- package/_dist/utils/index.d.ts +3 -0
- package/_dist/utils/index.d.ts.map +1 -0
- package/_dist/utils/index.js +19 -0
- package/_dist/utils/index.js.map +1 -0
- package/_dist/utils/payment.d.ts +3 -0
- package/_dist/utils/payment.d.ts.map +1 -0
- package/_dist/utils/payment.js +17 -0
- package/_dist/utils/payment.js.map +1 -0
- package/_dist/utils/serialize.d.ts +17 -0
- package/_dist/utils/serialize.d.ts.map +1 -0
- package/_dist/utils/serialize.js +77 -0
- package/_dist/utils/serialize.js.map +1 -0
- package/account/actions/getFeeQuote.ts +34 -0
- package/account/actions/index.ts +3 -0
- package/account/actions/sendTransaction.ts +61 -0
- package/account/actions/sendTransactionSync.ts +51 -0
- package/account/adapters/gelato/abi.ts +13 -0
- package/account/adapters/gelato/constants.ts +13 -0
- package/account/adapters/gelato/index.ts +216 -0
- package/account/adapters/index.ts +1 -0
- package/account/adapters/types/index.ts +36 -0
- package/account/index.ts +60 -0
- package/account/utils/delegation.ts +9 -0
- package/account/utils/estimation.ts +29 -0
- package/account/utils/index.ts +2 -0
- package/bundler/actions/estimateUserOperationGas.ts +63 -0
- package/bundler/actions/getUserOperationGasPrice.ts +25 -0
- package/bundler/actions/getUserOperationQuote.ts +83 -0
- package/bundler/actions/index.ts +6 -0
- package/bundler/actions/prepareUserOperation.ts +437 -0
- package/bundler/actions/sendUserOperation.ts +64 -0
- package/bundler/actions/sendUserOperationSync.ts +71 -0
- package/bundler/index.ts +98 -0
- package/index.ts +4 -0
- package/package.json +36 -0
- package/relayer/constants/index.ts +2 -0
- package/relayer/evm/actions/getCapabilities.ts +22 -0
- package/relayer/evm/actions/getFeeData.ts +36 -0
- package/relayer/evm/actions/getFeeQuote.ts +39 -0
- package/relayer/evm/actions/getStatus.ts +92 -0
- package/relayer/evm/actions/index.ts +7 -0
- package/relayer/evm/actions/sendTransaction.ts +33 -0
- package/relayer/evm/actions/sendTransactionSync.ts +30 -0
- package/relayer/evm/actions/waitForStatus.ts +24 -0
- package/relayer/evm/index.ts +68 -0
- package/relayer/index.ts +1 -0
- package/tsconfig.build.json +19 -0
- package/tsconfig.json +8 -0
- package/types/error.ts +38 -0
- package/types/index.ts +3 -0
- package/types/payment.ts +23 -0
- package/types/schema.ts +28 -0
- package/utils/index.ts +2 -0
- package/utils/payment.ts +20 -0
- package/utils/serialize.ts +91 -0
package/index.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gelatocloud/gasless",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"author": "Gelato",
|
|
5
|
+
"description": "Gelato Gasless SDK: All-in-one solution for gasless transactions",
|
|
6
|
+
"main": "./_dist/index.js",
|
|
7
|
+
"types": "./_dist/index.d.ts",
|
|
8
|
+
"typings": "./_dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./_dist/index.d.ts",
|
|
12
|
+
"import": "./_dist/index.js",
|
|
13
|
+
"default": "./_dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"zod": "4.1.13"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"typescript": "5.9.3",
|
|
21
|
+
"viem": "2.39.3"
|
|
22
|
+
},
|
|
23
|
+
"peerDependenciesMeta": {
|
|
24
|
+
"typescript": {
|
|
25
|
+
"optional": true
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"typescript": "5.9.3",
|
|
30
|
+
"viem": "2.39.3",
|
|
31
|
+
"zod": "4.1.13"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsc --project ./tsconfig.build.json"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Transport } from 'viem';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { evmAddressSchema, evmTokenSchema } from '../../../types/index.js';
|
|
4
|
+
|
|
5
|
+
const capabilitiesByChainSchema = z.object({
|
|
6
|
+
feeCollector: evmAddressSchema,
|
|
7
|
+
tokens: z.array(evmTokenSchema)
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const capabilitiesSchema = z.record(z.string().pipe(z.coerce.number()), capabilitiesByChainSchema);
|
|
11
|
+
|
|
12
|
+
export type CapabilitiesByChain = z.infer<typeof capabilitiesByChainSchema>;
|
|
13
|
+
export type Capabilities = z.infer<typeof capabilitiesSchema>;
|
|
14
|
+
|
|
15
|
+
export const getCapabilities = async (client: ReturnType<Transport>): Promise<Capabilities> => {
|
|
16
|
+
const result = await client.request({
|
|
17
|
+
method: 'relayer_getCapabilities',
|
|
18
|
+
params: []
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return capabilitiesSchema.parse(result);
|
|
22
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Address, Transport } from 'viem';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { evmTokenSchema } from '../../../types/index.js';
|
|
4
|
+
|
|
5
|
+
const feeDataSchema = z.object({
|
|
6
|
+
chainId: z.coerce.number(),
|
|
7
|
+
context: z.unknown().optional(),
|
|
8
|
+
expiry: z.number(),
|
|
9
|
+
gasPrice: z.coerce.bigint(),
|
|
10
|
+
rate: z.number(),
|
|
11
|
+
token: evmTokenSchema
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export type FeeData = z.infer<typeof feeDataSchema>;
|
|
15
|
+
|
|
16
|
+
export type GetFeeDataParameters = {
|
|
17
|
+
chainId: number;
|
|
18
|
+
token: Address;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const getFeeData = async (
|
|
22
|
+
client: ReturnType<Transport>,
|
|
23
|
+
parameters: GetFeeDataParameters
|
|
24
|
+
): Promise<FeeData> => {
|
|
25
|
+
const { chainId, token } = parameters;
|
|
26
|
+
|
|
27
|
+
const result = await client.request({
|
|
28
|
+
method: 'relayer_getFeeData',
|
|
29
|
+
params: {
|
|
30
|
+
chainId: chainId.toString(),
|
|
31
|
+
token
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return feeDataSchema.parse(result);
|
|
36
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Address, Transport } from 'viem';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { evmTokenSchema } from '../../../types/index.js';
|
|
4
|
+
|
|
5
|
+
const feeQuote = z.object({
|
|
6
|
+
chainId: z.coerce.number(),
|
|
7
|
+
context: z.unknown().optional(),
|
|
8
|
+
expiry: z.number(),
|
|
9
|
+
fee: z.coerce.bigint(),
|
|
10
|
+
token: evmTokenSchema
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export type FeeQuote = z.infer<typeof feeQuote>;
|
|
14
|
+
|
|
15
|
+
export type GetFeeQuoteParameters = {
|
|
16
|
+
chainId: number;
|
|
17
|
+
gas: bigint;
|
|
18
|
+
l1Fee?: bigint;
|
|
19
|
+
token: Address;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const getFeeQuote = async (
|
|
23
|
+
client: ReturnType<Transport>,
|
|
24
|
+
parameters: GetFeeQuoteParameters
|
|
25
|
+
): Promise<FeeQuote> => {
|
|
26
|
+
const { chainId, gas, l1Fee, token } = parameters;
|
|
27
|
+
|
|
28
|
+
const result = await client.request({
|
|
29
|
+
method: 'relayer_getFeeQuote',
|
|
30
|
+
params: {
|
|
31
|
+
chainId: chainId.toString(),
|
|
32
|
+
gas: gas.toString(),
|
|
33
|
+
l1Fee: l1Fee ? l1Fee.toString() : undefined,
|
|
34
|
+
token
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return feeQuote.parse(result);
|
|
39
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { Transport } from 'viem';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { evmAddressSchema, hexData32Schema, hexDataSchema } from '../../../types/index.js';
|
|
4
|
+
|
|
5
|
+
export enum StatusCode {
|
|
6
|
+
Pending = 100,
|
|
7
|
+
Submitted = 110,
|
|
8
|
+
Included = 200,
|
|
9
|
+
Rejected = 400,
|
|
10
|
+
Reverted = 500
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const logSchema = z.object({
|
|
14
|
+
address: evmAddressSchema,
|
|
15
|
+
data: hexDataSchema,
|
|
16
|
+
topics: z.array(hexData32Schema)
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const receiptSchema = z.object({
|
|
20
|
+
blockHash: hexData32Schema,
|
|
21
|
+
blockNumber: z.coerce.bigint(),
|
|
22
|
+
gasUsed: z.coerce.bigint(),
|
|
23
|
+
logs: z.array(logSchema).optional(),
|
|
24
|
+
transactionHash: hexData32Schema
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const baseStatusSchema = z.object({
|
|
28
|
+
chainId: z.coerce.number(),
|
|
29
|
+
createdAt: z.number()
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const pendingStatusSchema = baseStatusSchema.extend({
|
|
33
|
+
status: z.literal(StatusCode.Pending)
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const submittedStatusSchema = baseStatusSchema.extend({
|
|
37
|
+
hash: hexData32Schema,
|
|
38
|
+
status: z.literal(StatusCode.Submitted)
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const includedStatusSchema = baseStatusSchema.extend({
|
|
42
|
+
receipt: receiptSchema,
|
|
43
|
+
status: z.literal(StatusCode.Included)
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const rejectedStatusSchema = baseStatusSchema.extend({
|
|
47
|
+
data: z.unknown().optional(),
|
|
48
|
+
message: z.string(),
|
|
49
|
+
status: z.literal(StatusCode.Rejected)
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const revertedStatusSchema = baseStatusSchema.extend({
|
|
53
|
+
data: z.string(),
|
|
54
|
+
message: z.string().optional(),
|
|
55
|
+
status: z.literal(StatusCode.Reverted)
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const terminalStatusSchema = z.discriminatedUnion('status', [
|
|
59
|
+
includedStatusSchema,
|
|
60
|
+
rejectedStatusSchema,
|
|
61
|
+
revertedStatusSchema
|
|
62
|
+
]);
|
|
63
|
+
|
|
64
|
+
export const statusSchema = z.discriminatedUnion('status', [
|
|
65
|
+
pendingStatusSchema,
|
|
66
|
+
submittedStatusSchema,
|
|
67
|
+
includedStatusSchema,
|
|
68
|
+
rejectedStatusSchema,
|
|
69
|
+
revertedStatusSchema
|
|
70
|
+
]);
|
|
71
|
+
|
|
72
|
+
export type TerminalStatus = z.infer<typeof terminalStatusSchema>;
|
|
73
|
+
|
|
74
|
+
export type Status = z.infer<typeof statusSchema>;
|
|
75
|
+
|
|
76
|
+
export type GetStatusParameters = {
|
|
77
|
+
id: string;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const getStatus = async (
|
|
81
|
+
client: ReturnType<Transport>,
|
|
82
|
+
parameters: GetStatusParameters
|
|
83
|
+
): Promise<Status> => {
|
|
84
|
+
const { id } = parameters;
|
|
85
|
+
|
|
86
|
+
const result = await client.request({
|
|
87
|
+
method: 'relayer_getStatus',
|
|
88
|
+
params: { id }
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return statusSchema.parse(result);
|
|
92
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Address, Hex, SignedAuthorizationList, Transport } from 'viem';
|
|
2
|
+
import { hexData32Schema, type Payment } from '../../../types/index.js';
|
|
3
|
+
import { formatAuthorization } from '../../../utils/index.js';
|
|
4
|
+
|
|
5
|
+
export type SendTransactionParameters = {
|
|
6
|
+
authorizationList?: SignedAuthorizationList;
|
|
7
|
+
chainId: number;
|
|
8
|
+
context?: unknown;
|
|
9
|
+
data: Hex;
|
|
10
|
+
payment: Payment;
|
|
11
|
+
to: Address;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const sendTransaction = async (
|
|
15
|
+
client: ReturnType<Transport>,
|
|
16
|
+
parameters: SendTransactionParameters
|
|
17
|
+
): Promise<Hex> => {
|
|
18
|
+
const { chainId, data, to, payment, context, authorizationList } = parameters;
|
|
19
|
+
|
|
20
|
+
const result = await client.request({
|
|
21
|
+
method: 'relayer_sendTransaction',
|
|
22
|
+
params: {
|
|
23
|
+
authorizationList: authorizationList ? authorizationList.map(formatAuthorization) : undefined,
|
|
24
|
+
chainId: chainId.toString(),
|
|
25
|
+
context,
|
|
26
|
+
data,
|
|
27
|
+
payment,
|
|
28
|
+
to
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
return hexData32Schema.parse(result);
|
|
33
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Transport } from 'viem';
|
|
2
|
+
import { formatAuthorization } from '../../../utils/index.js';
|
|
3
|
+
import { type TerminalStatus, terminalStatusSchema } from './getStatus.js';
|
|
4
|
+
import type { SendTransactionParameters } from './sendTransaction.js';
|
|
5
|
+
|
|
6
|
+
export type SendTransactionSyncParameters = SendTransactionParameters & {
|
|
7
|
+
timeout?: number;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const sendTransactionSync = async (
|
|
11
|
+
client: ReturnType<Transport>,
|
|
12
|
+
parameters: SendTransactionSyncParameters
|
|
13
|
+
): Promise<TerminalStatus> => {
|
|
14
|
+
const { chainId, data, to, payment, context, authorizationList, timeout } = parameters;
|
|
15
|
+
|
|
16
|
+
const result = await client.request({
|
|
17
|
+
method: 'relayer_sendTransactionSync',
|
|
18
|
+
params: {
|
|
19
|
+
authorizationList: authorizationList ? authorizationList.map(formatAuthorization) : undefined,
|
|
20
|
+
chainId: chainId.toString(),
|
|
21
|
+
context,
|
|
22
|
+
data,
|
|
23
|
+
payment,
|
|
24
|
+
timeout,
|
|
25
|
+
to
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
return terminalStatusSchema.parse(result);
|
|
30
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Transport } from 'viem';
|
|
2
|
+
import {
|
|
3
|
+
type GetStatusParameters,
|
|
4
|
+
getStatus,
|
|
5
|
+
StatusCode,
|
|
6
|
+
type TerminalStatus
|
|
7
|
+
} from './getStatus.js';
|
|
8
|
+
|
|
9
|
+
// TODO: use websockets
|
|
10
|
+
// TODO: make polling interval configurable
|
|
11
|
+
export const waitForStatus = async (
|
|
12
|
+
client: ReturnType<Transport>,
|
|
13
|
+
parameters: GetStatusParameters
|
|
14
|
+
): Promise<TerminalStatus> => {
|
|
15
|
+
while (true) {
|
|
16
|
+
const status = await getStatus(client, parameters);
|
|
17
|
+
|
|
18
|
+
if (status.status !== StatusCode.Pending && status.status !== StatusCode.Submitted) {
|
|
19
|
+
return status;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
23
|
+
}
|
|
24
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type Hex, type HttpTransportConfig, http } from 'viem';
|
|
2
|
+
import { GELATO_PROD_API, GELATO_STAGING_API } from '../constants/index.js';
|
|
3
|
+
import {
|
|
4
|
+
type Capabilities,
|
|
5
|
+
type FeeData,
|
|
6
|
+
type FeeQuote,
|
|
7
|
+
type GetFeeDataParameters,
|
|
8
|
+
type GetFeeQuoteParameters,
|
|
9
|
+
type GetStatusParameters,
|
|
10
|
+
getCapabilities,
|
|
11
|
+
getFeeData,
|
|
12
|
+
getFeeQuote,
|
|
13
|
+
getStatus,
|
|
14
|
+
type SendTransactionParameters,
|
|
15
|
+
type SendTransactionSyncParameters,
|
|
16
|
+
type Status,
|
|
17
|
+
sendTransaction,
|
|
18
|
+
sendTransactionSync,
|
|
19
|
+
type TerminalStatus,
|
|
20
|
+
waitForStatus
|
|
21
|
+
} from './actions/index.js';
|
|
22
|
+
|
|
23
|
+
export * from './actions/index.js';
|
|
24
|
+
|
|
25
|
+
export type GelatoEvmRelayerClient = {
|
|
26
|
+
getCapabilities: () => Promise<Capabilities>;
|
|
27
|
+
getFeeData: (parameters: GetFeeDataParameters) => Promise<FeeData>;
|
|
28
|
+
getFeeQuote: (parameters: GetFeeQuoteParameters) => Promise<FeeQuote>;
|
|
29
|
+
getStatus: (parameters: GetStatusParameters) => Promise<Status>;
|
|
30
|
+
waitForStatus: (parameters: GetStatusParameters) => Promise<TerminalStatus>;
|
|
31
|
+
sendTransaction: (parameters: SendTransactionParameters) => Promise<Hex>;
|
|
32
|
+
sendTransactionSync: (parameters: SendTransactionSyncParameters) => Promise<TerminalStatus>;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type GelatoEvmRelayerClientConfig = {
|
|
36
|
+
apiKey: string;
|
|
37
|
+
testnet: boolean;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// TODO: the testnet/mainnet separation won't be necessary in the future
|
|
41
|
+
export const createGelatoEvmRelayerClient = (
|
|
42
|
+
parameters: GelatoEvmRelayerClientConfig
|
|
43
|
+
): GelatoEvmRelayerClient => {
|
|
44
|
+
const { apiKey, testnet } = parameters;
|
|
45
|
+
|
|
46
|
+
const config: HttpTransportConfig = {
|
|
47
|
+
fetchOptions: {
|
|
48
|
+
headers: {
|
|
49
|
+
'X-API-Key': apiKey
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// TODO: can just use prod endpoint in the future
|
|
55
|
+
const base = testnet ? GELATO_STAGING_API : GELATO_PROD_API;
|
|
56
|
+
|
|
57
|
+
const client = http(`${base}/rpc`, config)({});
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
getCapabilities: () => getCapabilities(client),
|
|
61
|
+
getFeeData: (parameters) => getFeeData(client, parameters),
|
|
62
|
+
getFeeQuote: (parameters) => getFeeQuote(client, parameters),
|
|
63
|
+
getStatus: (parameters) => getStatus(client, parameters),
|
|
64
|
+
sendTransaction: (parameters) => sendTransaction(client, parameters),
|
|
65
|
+
sendTransactionSync: (parameters) => sendTransactionSync(client, parameters),
|
|
66
|
+
waitForStatus: (parameters) => waitForStatus(client, parameters)
|
|
67
|
+
};
|
|
68
|
+
};
|
package/relayer/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './evm/index.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"declaration": true,
|
|
5
|
+
"declarationMap": true,
|
|
6
|
+
"sourceMap": true,
|
|
7
|
+
"composite": true,
|
|
8
|
+
"noEmit": false,
|
|
9
|
+
"outDir": "./_dist"
|
|
10
|
+
},
|
|
11
|
+
"exclude": [
|
|
12
|
+
"node_modules",
|
|
13
|
+
"_dist",
|
|
14
|
+
"**/*.test.ts",
|
|
15
|
+
"**/*.spec.ts",
|
|
16
|
+
"**/*.test.tsx",
|
|
17
|
+
"**/*.spec.tsx"
|
|
18
|
+
]
|
|
19
|
+
}
|
package/tsconfig.json
ADDED
package/types/error.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Note: copied from viem since it doesn't export these
|
|
2
|
+
|
|
3
|
+
import { BaseError } from 'viem';
|
|
4
|
+
|
|
5
|
+
export class InvalidBytesLengthError extends BaseError {
|
|
6
|
+
constructor({
|
|
7
|
+
size,
|
|
8
|
+
targetSize,
|
|
9
|
+
type
|
|
10
|
+
}: {
|
|
11
|
+
size: number;
|
|
12
|
+
targetSize: number;
|
|
13
|
+
type: 'hex' | 'bytes';
|
|
14
|
+
}) {
|
|
15
|
+
super(
|
|
16
|
+
`${type.charAt(0).toUpperCase()}${type
|
|
17
|
+
.slice(1)
|
|
18
|
+
.toLowerCase()} is expected to be ${targetSize} ${type} long, but is ${size} ${type} long.`,
|
|
19
|
+
{ name: 'InvalidBytesLengthError' }
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class AccountNotFoundError extends BaseError {
|
|
25
|
+
constructor({ docsPath }: { docsPath?: string | undefined } = {}) {
|
|
26
|
+
super(
|
|
27
|
+
[
|
|
28
|
+
'Could not find an Account to execute with this Action.',
|
|
29
|
+
'Please provide an Account with the `account` argument on the Action, or by supplying an `account` to the Client.'
|
|
30
|
+
].join('\n'),
|
|
31
|
+
{
|
|
32
|
+
docsPath,
|
|
33
|
+
docsSlug: 'account',
|
|
34
|
+
name: 'AccountNotFoundError'
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
package/types/index.ts
ADDED
package/types/payment.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type Address, zeroAddress } from 'viem';
|
|
2
|
+
|
|
3
|
+
export enum PaymentType {
|
|
4
|
+
Token = 'token',
|
|
5
|
+
Sponsored = 'sponsored'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type TokenPayment = {
|
|
9
|
+
type: PaymentType.Token;
|
|
10
|
+
address: Address;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type SponsoredPayment = {
|
|
14
|
+
type: PaymentType.Sponsored;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type Payment = TokenPayment | SponsoredPayment;
|
|
18
|
+
|
|
19
|
+
export const sponsored = (): Payment => ({ type: PaymentType.Sponsored });
|
|
20
|
+
|
|
21
|
+
export const token = (address: Address): Payment => ({ address, type: PaymentType.Token });
|
|
22
|
+
|
|
23
|
+
export const native = (): Payment => ({ address: zeroAddress, type: PaymentType.Token });
|
package/types/schema.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getAddress, type Hex } from 'viem';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
const hexData32Pattern = /^0x([0-9a-fA-F][0-9a-fA-F]){32}$/;
|
|
5
|
+
const hexDataPattern = /^0x([0-9a-fA-F][0-9a-fA-F])*$/;
|
|
6
|
+
const evmAddressPattern = /^0x([0-9a-fA-F][0-9a-fA-F]){20}$/;
|
|
7
|
+
|
|
8
|
+
export const hexDataSchema = z
|
|
9
|
+
.string()
|
|
10
|
+
.regex(hexDataPattern, { message: 'not valid hex data' })
|
|
11
|
+
.transform((val) => val as Hex);
|
|
12
|
+
|
|
13
|
+
export const hexData32Schema = z
|
|
14
|
+
.string()
|
|
15
|
+
.regex(hexData32Pattern, { message: 'not valid 32-byte hex data' })
|
|
16
|
+
.transform((val) => val as Hex);
|
|
17
|
+
|
|
18
|
+
export const evmAddressSchema = z
|
|
19
|
+
.string()
|
|
20
|
+
.regex(evmAddressPattern, { message: 'not a valid EVM address' })
|
|
21
|
+
.transform((val) => getAddress(val));
|
|
22
|
+
|
|
23
|
+
export const evmTokenSchema = z.object({
|
|
24
|
+
address: evmAddressSchema,
|
|
25
|
+
decimals: z.number()
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export type EvmToken = z.infer<typeof evmTokenSchema>;
|
package/utils/index.ts
ADDED
package/utils/payment.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Address, type Call, encodeFunctionData, erc20Abi, zeroAddress } from 'viem';
|
|
2
|
+
|
|
3
|
+
export const appendPayment = (
|
|
4
|
+
calls: Call[],
|
|
5
|
+
token: Address,
|
|
6
|
+
feeCollector: Address,
|
|
7
|
+
amount: bigint
|
|
8
|
+
): Call[] => {
|
|
9
|
+
if (token === zeroAddress) {
|
|
10
|
+
return [...calls, { to: feeCollector, value: amount }];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const data = encodeFunctionData({
|
|
14
|
+
abi: erc20Abi,
|
|
15
|
+
args: [feeCollector, amount],
|
|
16
|
+
functionName: 'transfer'
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
return [...calls, { data, to: token }];
|
|
20
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Note: copied from viem since it doesn't export these
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AccountStateConflictError,
|
|
5
|
+
InvalidAddressError,
|
|
6
|
+
isAddress,
|
|
7
|
+
numberToHex,
|
|
8
|
+
pad,
|
|
9
|
+
type RpcAccountStateOverride,
|
|
10
|
+
type RpcStateMapping,
|
|
11
|
+
type RpcStateOverride,
|
|
12
|
+
type SignedAuthorization,
|
|
13
|
+
StateAssignmentConflictError,
|
|
14
|
+
type StateMapping,
|
|
15
|
+
type StateOverride
|
|
16
|
+
} from 'viem';
|
|
17
|
+
import { InvalidBytesLengthError } from '../types/index.js';
|
|
18
|
+
|
|
19
|
+
type SerializeStateMappingParameters = StateMapping | undefined;
|
|
20
|
+
|
|
21
|
+
export function serializeStateMapping(
|
|
22
|
+
stateMapping: SerializeStateMappingParameters
|
|
23
|
+
): RpcStateMapping | undefined {
|
|
24
|
+
if (!stateMapping || stateMapping.length === 0) return undefined;
|
|
25
|
+
return stateMapping.reduce((acc, { slot, value }) => {
|
|
26
|
+
if (slot.length !== 66)
|
|
27
|
+
throw new InvalidBytesLengthError({
|
|
28
|
+
size: slot.length,
|
|
29
|
+
targetSize: 66,
|
|
30
|
+
type: 'hex'
|
|
31
|
+
});
|
|
32
|
+
if (value.length !== 66)
|
|
33
|
+
throw new InvalidBytesLengthError({
|
|
34
|
+
size: value.length,
|
|
35
|
+
targetSize: 66,
|
|
36
|
+
type: 'hex'
|
|
37
|
+
});
|
|
38
|
+
acc[slot] = value;
|
|
39
|
+
return acc;
|
|
40
|
+
}, {} as RpcStateMapping);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type SerializeAccountStateOverrideParameters = Omit<StateOverride[number], 'address'>;
|
|
44
|
+
|
|
45
|
+
export function serializeAccountStateOverride(
|
|
46
|
+
parameters: SerializeAccountStateOverrideParameters
|
|
47
|
+
): RpcAccountStateOverride {
|
|
48
|
+
const { balance, nonce, state, stateDiff, code } = parameters;
|
|
49
|
+
const rpcAccountStateOverride: RpcAccountStateOverride = {};
|
|
50
|
+
if (code !== undefined) rpcAccountStateOverride.code = code;
|
|
51
|
+
if (balance !== undefined) rpcAccountStateOverride.balance = numberToHex(balance);
|
|
52
|
+
if (nonce !== undefined) rpcAccountStateOverride.nonce = numberToHex(nonce);
|
|
53
|
+
if (state !== undefined) rpcAccountStateOverride.state = serializeStateMapping(state);
|
|
54
|
+
if (stateDiff !== undefined) {
|
|
55
|
+
if (rpcAccountStateOverride.state) throw new StateAssignmentConflictError();
|
|
56
|
+
rpcAccountStateOverride.stateDiff = serializeStateMapping(stateDiff);
|
|
57
|
+
}
|
|
58
|
+
return rpcAccountStateOverride;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
type SerializeStateOverrideParameters = StateOverride | undefined;
|
|
62
|
+
|
|
63
|
+
export function serializeStateOverride(
|
|
64
|
+
parameters?: SerializeStateOverrideParameters
|
|
65
|
+
): RpcStateOverride | undefined {
|
|
66
|
+
if (!parameters) return undefined;
|
|
67
|
+
const rpcStateOverride: RpcStateOverride = {};
|
|
68
|
+
for (const { address, ...accountState } of parameters) {
|
|
69
|
+
if (!isAddress(address, { strict: false })) throw new InvalidAddressError({ address });
|
|
70
|
+
if (rpcStateOverride[address]) throw new AccountStateConflictError({ address: address });
|
|
71
|
+
rpcStateOverride[address] = serializeAccountStateOverride(accountState);
|
|
72
|
+
}
|
|
73
|
+
return rpcStateOverride;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function formatAuthorization(authorization: SignedAuthorization) {
|
|
77
|
+
return {
|
|
78
|
+
address: authorization.address,
|
|
79
|
+
chainId: numberToHex(authorization.chainId),
|
|
80
|
+
nonce: numberToHex(authorization.nonce),
|
|
81
|
+
r: authorization.r
|
|
82
|
+
? numberToHex(BigInt(authorization.r), { size: 32 })
|
|
83
|
+
: pad('0x', { size: 32 }),
|
|
84
|
+
s: authorization.s
|
|
85
|
+
? numberToHex(BigInt(authorization.s), { size: 32 })
|
|
86
|
+
: pad('0x', { size: 32 }),
|
|
87
|
+
yParity: authorization.yParity
|
|
88
|
+
? numberToHex(authorization.yParity, { size: 1 })
|
|
89
|
+
: pad('0x', { size: 32 })
|
|
90
|
+
};
|
|
91
|
+
}
|