@polymarket/relayer-client 4.0.0 → 4.1.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.
Files changed (55) hide show
  1. package/dist/abis/erc20Abi.d.ts +38 -0
  2. package/dist/abis/erc20Abi.js +222 -0
  3. package/dist/abis/index.d.ts +5 -0
  4. package/dist/abis/index.js +5 -0
  5. package/dist/abis/multisend.d.ts +13 -0
  6. package/dist/abis/multisend.js +17 -0
  7. package/dist/abis/proxyFactory.d.ts +66 -0
  8. package/dist/abis/proxyFactory.js +319 -0
  9. package/dist/abis/safe.d.ts +35 -0
  10. package/dist/abis/safe.js +1138 -0
  11. package/dist/abis/safeFactory.d.ts +60 -0
  12. package/dist/abis/safeFactory.js +224 -0
  13. package/dist/auth/handler.d.ts +15 -0
  14. package/dist/auth/handler.js +46 -0
  15. package/dist/auth/index.d.ts +1 -0
  16. package/dist/auth/index.js +1 -0
  17. package/dist/builder/create.d.ts +4 -0
  18. package/dist/builder/create.js +48 -0
  19. package/dist/builder/derive.d.ts +2 -0
  20. package/dist/builder/derive.js +16 -0
  21. package/dist/builder/index.d.ts +4 -0
  22. package/dist/builder/index.js +4 -0
  23. package/dist/builder/proxy.d.ts +4 -0
  24. package/dist/builder/proxy.js +72 -0
  25. package/dist/builder/safe.d.ts +5 -0
  26. package/dist/builder/safe.js +105 -0
  27. package/dist/client.d.ts +39 -0
  28. package/dist/client.js +173 -0
  29. package/dist/config/index.d.ts +13 -0
  30. package/dist/config/index.js +30 -0
  31. package/dist/constants/index.d.ts +3 -0
  32. package/dist/constants/index.js +3 -0
  33. package/dist/encode/index.d.ts +2 -0
  34. package/dist/encode/index.js +2 -0
  35. package/dist/encode/proxy.d.ts +2 -0
  36. package/dist/encode/proxy.js +12 -0
  37. package/dist/encode/safe.d.ts +2 -0
  38. package/dist/encode/safe.js +25 -0
  39. package/dist/endpoints.d.ts +5 -0
  40. package/dist/endpoints.js +5 -0
  41. package/dist/http-helpers/index.d.ts +10 -0
  42. package/dist/http-helpers/index.js +46 -0
  43. package/dist/index.d.ts +4 -0
  44. package/dist/index.js +4 -0
  45. package/dist/manual/index.d.ts +5 -0
  46. package/dist/manual/index.js +49 -0
  47. package/dist/response/index.d.ts +21 -0
  48. package/dist/response/index.js +34 -0
  49. package/dist/signer/index.d.ts +26 -0
  50. package/dist/signer/index.js +109 -0
  51. package/dist/types.d.ts +132 -0
  52. package/dist/types.js +27 -0
  53. package/dist/utils/index.d.ts +7 -0
  54. package/dist/utils/index.js +30 -0
  55. package/package.json +8 -2
package/dist/client.js ADDED
@@ -0,0 +1,173 @@
1
+ import { isBrowser } from "browser-or-node";
2
+ import { zeroAddress } from "viem";
3
+ import { AuthHandler } from "./auth/handler.js";
4
+ import { buildProxyTransactionRequest, buildSafeCreateTransactionRequest, buildSafeTransactionRequest, } from "./builder/index.js";
5
+ import { getContractConfig } from "./config/index.js";
6
+ import { encodeProxyTransactionData } from "./encode/index.js";
7
+ import { GET_ADDRESS, GET_NONCE, GET_RELAY_PAYLOAD, GET_TRANSACTION, SUBMIT_TRANSACTION, } from "./endpoints.js";
8
+ import { GET, HttpClient, POST } from "./http-helpers/index.js";
9
+ import { executeManualTransactions } from "./manual/index.js";
10
+ import { ClientRelayerTransactionResponse } from "./response/index.js";
11
+ import { createViemSigner } from "./signer/index.js";
12
+ import { TransactionType, } from "./types.js";
13
+ import { sleep } from "./utils/index.js";
14
+ export class RelayClient {
15
+ relayerUrl;
16
+ chainId;
17
+ contractConfig;
18
+ httpClient;
19
+ signer;
20
+ authHandler;
21
+ constructor(relayerUrl, chainId, signer, authArgs) {
22
+ this.relayerUrl = relayerUrl.endsWith("/") ? relayerUrl.slice(0, -1) : relayerUrl;
23
+ this.chainId = chainId;
24
+ this.contractConfig = getContractConfig(chainId);
25
+ this.httpClient = new HttpClient();
26
+ if (signer !== undefined) {
27
+ this.signer = createViemSigner(chainId, signer);
28
+ }
29
+ if (authArgs !== undefined) {
30
+ this.authHandler = new AuthHandler(this.httpClient, authArgs);
31
+ }
32
+ }
33
+ async getRelayAddress() {
34
+ return this.send(`${this.relayerUrl}${GET_ADDRESS}`, GET);
35
+ }
36
+ async getNonce(signerAddress, signerType) {
37
+ return this.send(`${this.relayerUrl}${GET_NONCE}?address=${signerAddress}&type=${signerType}`, GET);
38
+ }
39
+ async getRelayPayload(signerAddress, signerType) {
40
+ return this.send(`${this.relayerUrl}${GET_RELAY_PAYLOAD}?address=${signerAddress}&type=${signerType}`, GET);
41
+ }
42
+ async getTransaction(transactionId) {
43
+ return this.send(`${this.relayerUrl}${GET_TRANSACTION}?id=${transactionId}`, GET);
44
+ }
45
+ async getTransactions() {
46
+ return this.send(`${this.relayerUrl}${GET_TRANSACTION}s`, GET);
47
+ }
48
+ async executeProxyTransactions(txns, metadata) {
49
+ if (this.signer === undefined) {
50
+ throw new Error("missing signer");
51
+ }
52
+ const start = Date.now();
53
+ const from = await this.signer.getAddress();
54
+ const rp = await this.getRelayPayload(from, TransactionType.PROXY);
55
+ const args = {
56
+ from: from,
57
+ gasPrice: "0",
58
+ data: encodeProxyTransactionData(txns),
59
+ relay: rp.address,
60
+ nonce: rp.nonce,
61
+ };
62
+ const proxyContractConfig = this.contractConfig.ProxyContracts;
63
+ const request = await buildProxyTransactionRequest(this.signer, args, proxyContractConfig, metadata);
64
+ console.log(`Client side proxy request creation took: ${(Date.now() - start) / 1000} seconds`);
65
+ const resp = await this.submitTransaction(request);
66
+ return new ClientRelayerTransactionResponse(resp.transactionID, resp.state, resp.transactionHash, this);
67
+ }
68
+ async executeSafeTransactions(txns, metadata) {
69
+ if (this.signer === undefined) {
70
+ throw new Error("missing signer");
71
+ }
72
+ const start = Date.now();
73
+ const from = await this.signer.getAddress();
74
+ const noncePayload = await this.getNonce(from, TransactionType.SAFE);
75
+ const args = {
76
+ transactions: txns,
77
+ from,
78
+ nonce: noncePayload.nonce,
79
+ chainId: this.chainId,
80
+ };
81
+ const safeContractConfig = this.contractConfig.SafeContracts;
82
+ const request = await buildSafeTransactionRequest(this.signer, args, safeContractConfig, metadata);
83
+ console.log(`Client side safe request creation took: ${(Date.now() - start) / 1000} seconds`);
84
+ const resp = await this.submitTransaction(request);
85
+ return new ClientRelayerTransactionResponse(resp.transactionID, resp.state, resp.transactionHash, this);
86
+ }
87
+ async executeManualTransactions(txns, overrides) {
88
+ if (overrides === undefined) {
89
+ overrides = {};
90
+ }
91
+ if (this.signer === undefined) {
92
+ throw new Error("missing signer");
93
+ }
94
+ return executeManualTransactions(this.signer, this.contractConfig.SafeContracts, txns, overrides);
95
+ }
96
+ async deploySafe() {
97
+ if (this.signer === undefined) {
98
+ throw new Error("missing signer");
99
+ }
100
+ const start = Date.now();
101
+ const from = await this.signer?.getAddress();
102
+ const args = {
103
+ from: from,
104
+ chainId: this.chainId,
105
+ paymentToken: zeroAddress,
106
+ payment: "0",
107
+ paymentReceiver: zeroAddress,
108
+ };
109
+ const safeContractConfig = this.contractConfig.SafeContracts;
110
+ const request = await buildSafeCreateTransactionRequest(this.signer, safeContractConfig, args);
111
+ console.log(`Client side deploy request creation took: ${(Date.now() - start) / 1000} seconds`);
112
+ const resp = await this.submitTransaction(request);
113
+ return new ClientRelayerTransactionResponse(resp.transactionID, resp.state, resp.transactionHash, this);
114
+ }
115
+ /**
116
+ * Periodically polls the transaction id until it reaches a desired state
117
+ * Returns the relayer transaction if it does each the desired state
118
+ * Returns undefined if the transaction hits the failed state
119
+ * Times out after maxPolls is reached
120
+ * @param transactionId
121
+ * @param states
122
+ * @param failState
123
+ * @param maxPolls
124
+ * @param pollFrequency
125
+ * @returns
126
+ */
127
+ async pollUntilState(transactionId, states, failState, maxPolls, pollFrequency) {
128
+ console.log(`Waiting for transaction ${transactionId} matching states: ${states}...`);
129
+ const maxPollCount = maxPolls !== undefined ? maxPolls : 10;
130
+ let pollFreq = 2000; // Default to polling every 2 seconds
131
+ if (pollFrequency !== undefined) {
132
+ if (pollFrequency >= 1000) {
133
+ pollFreq = pollFrequency;
134
+ }
135
+ }
136
+ let pollCount = 0;
137
+ while (pollCount < maxPollCount) {
138
+ const txns = await this.getTransaction(transactionId);
139
+ if (txns.length > 0) {
140
+ const txn = txns[0];
141
+ if (states.includes(txn.state)) {
142
+ return txn;
143
+ }
144
+ if (failState !== undefined && txn.state === failState) {
145
+ // Return undefined if txn reaches the fail state
146
+ return undefined;
147
+ }
148
+ }
149
+ pollCount++;
150
+ await sleep(pollFreq);
151
+ }
152
+ console.log(`Transaction not found or not in given states, timing out`);
153
+ }
154
+ async submitTransaction(req) {
155
+ return this.send(`${this.relayerUrl}${SUBMIT_TRANSACTION}`, POST, undefined, req);
156
+ }
157
+ async send(endpoint, method, headers, data, params) {
158
+ // Explicitly inject the polymarket session cookies
159
+ // In prod environments, this will be unnecessary as the browser will have the needed cookies
160
+ // Needed only for local testing
161
+ if (!isBrowser && this.authHandler !== undefined) {
162
+ const cookie = await this.authHandler.getPolymarketCookies();
163
+ if (headers !== undefined) {
164
+ headers.Cookie = cookie;
165
+ }
166
+ else {
167
+ headers = { Cookie: cookie };
168
+ }
169
+ }
170
+ const resp = await this.httpClient.send(endpoint, method, headers, data, params);
171
+ return resp.data;
172
+ }
173
+ }
@@ -0,0 +1,13 @@
1
+ export interface ProxyContractConfig {
2
+ RelayHub: string;
3
+ ProxyFactory: string;
4
+ }
5
+ export interface SafeContractConfig {
6
+ SafeFactory: string;
7
+ SafeMultisend: string;
8
+ }
9
+ export interface ContractConfig {
10
+ ProxyContracts: ProxyContractConfig;
11
+ SafeContracts: SafeContractConfig;
12
+ }
13
+ export declare const getContractConfig: (chainId: number) => ContractConfig;
@@ -0,0 +1,30 @@
1
+ const AMOY = {
2
+ ProxyContracts: {
3
+ ProxyFactory: "",
4
+ RelayHub: "",
5
+ },
6
+ SafeContracts: {
7
+ SafeFactory: "",
8
+ SafeMultisend: "",
9
+ },
10
+ };
11
+ const POL = {
12
+ ProxyContracts: {
13
+ ProxyFactory: "0xaB45c5A4B0c941a2F231C04C3f49182e1A254052",
14
+ RelayHub: "0xD216153c06E857cD7f72665E0aF1d7D82172F494",
15
+ },
16
+ SafeContracts: {
17
+ SafeFactory: "0xaacFeEa03eb1561C4e67d661e40682Bd20E3541b",
18
+ SafeMultisend: "0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761",
19
+ },
20
+ };
21
+ export const getContractConfig = (chainId) => {
22
+ switch (chainId) {
23
+ case 137:
24
+ return POL;
25
+ case 80002:
26
+ return AMOY;
27
+ default:
28
+ throw new Error("Invalid network");
29
+ }
30
+ };
@@ -0,0 +1,3 @@
1
+ export declare const PROXY_INIT_CODE_HASH = "0xd21df8dc65880a8606f09fe0ce3df9b8869287ab0b058be05aa9e8af6330a00b";
2
+ export declare const SAFE_INIT_CODE_HASH = "0x2bce2127ff07fb632d16c8347c4ebf501f4841168bed00d9e6ef715ddb6fcecf";
3
+ export declare const SAFE_FACTORY_NAME = "Polymarket Contract Proxy Factory";
@@ -0,0 +1,3 @@
1
+ export const PROXY_INIT_CODE_HASH = "0xd21df8dc65880a8606f09fe0ce3df9b8869287ab0b058be05aa9e8af6330a00b";
2
+ export const SAFE_INIT_CODE_HASH = "0x2bce2127ff07fb632d16c8347c4ebf501f4841168bed00d9e6ef715ddb6fcecf";
3
+ export const SAFE_FACTORY_NAME = "Polymarket Contract Proxy Factory";
@@ -0,0 +1,2 @@
1
+ export * from "./proxy.ts";
2
+ export * from "./safe.ts";
@@ -0,0 +1,2 @@
1
+ export * from "./proxy.js";
2
+ export * from "./safe.js";
@@ -0,0 +1,2 @@
1
+ import type { ProxyTransaction } from "../types.ts";
2
+ export declare function encodeProxyTransactionData(txns: ProxyTransaction[]): string;
@@ -0,0 +1,12 @@
1
+ import { encodeFunctionData, prepareEncodeFunctionData } from "viem";
2
+ import { proxyWalletFactory } from "../abis/index.js";
3
+ const proxy = prepareEncodeFunctionData({
4
+ abi: proxyWalletFactory,
5
+ functionName: "proxy",
6
+ });
7
+ export function encodeProxyTransactionData(txns) {
8
+ return encodeFunctionData({
9
+ ...proxy,
10
+ args: [txns],
11
+ });
12
+ }
@@ -0,0 +1,2 @@
1
+ import { type SafeTransaction } from "../types.ts";
2
+ export declare const createSafeMultisendTransaction: (txns: SafeTransaction[], safeMultisendAddress: string) => SafeTransaction;
@@ -0,0 +1,25 @@
1
+ import { concatHex, encodeFunctionData, encodePacked, prepareEncodeFunctionData, size, } from "viem";
2
+ import { multisendAbi } from "../abis/index.js";
3
+ import { OperationType } from "../types.js";
4
+ const multisend = prepareEncodeFunctionData({
5
+ abi: multisendAbi,
6
+ functionName: "multiSend",
7
+ });
8
+ export const createSafeMultisendTransaction = (txns, safeMultisendAddress) => {
9
+ const args = [
10
+ concatHex(txns.map(tx => encodePacked(["uint8", "address", "uint256", "uint256", "bytes"], [
11
+ tx.operation,
12
+ tx.to,
13
+ BigInt(tx.value),
14
+ BigInt(size(tx.data)),
15
+ tx.data,
16
+ ]))),
17
+ ];
18
+ const data = encodeFunctionData({ ...multisend, args: args });
19
+ return {
20
+ to: safeMultisendAddress,
21
+ value: "0",
22
+ data: data,
23
+ operation: OperationType.DelegateCall,
24
+ };
25
+ };
@@ -0,0 +1,5 @@
1
+ export declare const GET_ADDRESS = "/address";
2
+ export declare const GET_NONCE = "/nonce";
3
+ export declare const GET_RELAY_PAYLOAD = "/relay-payload";
4
+ export declare const GET_TRANSACTION = "/transaction";
5
+ export declare const SUBMIT_TRANSACTION = "/submit";
@@ -0,0 +1,5 @@
1
+ export const GET_ADDRESS = "/address";
2
+ export const GET_NONCE = "/nonce";
3
+ export const GET_RELAY_PAYLOAD = "/relay-payload";
4
+ export const GET_TRANSACTION = "/transaction";
5
+ export const SUBMIT_TRANSACTION = "/submit";
@@ -0,0 +1,10 @@
1
+ import { type AxiosInstance, type AxiosResponse, type Method } from "axios";
2
+ export declare const GET = "GET";
3
+ export declare const POST = "POST";
4
+ export declare const DELETE = "DELETE";
5
+ export declare const PUT = "PUT";
6
+ export declare class HttpClient {
7
+ readonly instance: AxiosInstance;
8
+ constructor();
9
+ send(endpoint: string, method: Method, headers?: any, data?: any, params?: any): Promise<AxiosResponse>;
10
+ }
@@ -0,0 +1,46 @@
1
+ import axios from "axios";
2
+ export const GET = "GET";
3
+ export const POST = "POST";
4
+ export const DELETE = "DELETE";
5
+ export const PUT = "PUT";
6
+ export class HttpClient {
7
+ instance;
8
+ constructor() {
9
+ this.instance = axios.create({ withCredentials: true });
10
+ }
11
+ async send(endpoint, method, headers, data, params) {
12
+ if (headers !== undefined) {
13
+ headers["Access-Control-Allow-Credentials"] = true;
14
+ }
15
+ try {
16
+ const resp = await this.instance.request({
17
+ method,
18
+ url: endpoint,
19
+ headers,
20
+ data,
21
+ params,
22
+ });
23
+ return resp;
24
+ }
25
+ catch (err) {
26
+ if (axios.isAxiosError(err)) {
27
+ if (err.response) {
28
+ const errPayload = {
29
+ error: "request error",
30
+ status: err.response?.status,
31
+ statusText: err.response?.statusText,
32
+ data: err.response?.data,
33
+ };
34
+ console.error("request error", errPayload);
35
+ throw new Error(JSON.stringify(errPayload));
36
+ }
37
+ else {
38
+ const errPayload = { error: "connection error" };
39
+ console.error("connection error", errPayload);
40
+ throw new Error(JSON.stringify(errPayload));
41
+ }
42
+ }
43
+ throw new Error(JSON.stringify({ error: err }));
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./client.ts";
2
+ export * from "./encode/index.ts";
3
+ export * from "./response/index.ts";
4
+ export * from "./types.ts";
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from "./client.js";
2
+ export * from "./encode/index.js";
3
+ export * from "./response/index.js";
4
+ export * from "./types.js";
@@ -0,0 +1,5 @@
1
+ import type { SafeContractConfig } from "../config/index.ts";
2
+ import { ManualTransactionResponse } from "../response/index.ts";
3
+ import type { RelayerSigner } from "../signer/index.ts";
4
+ import type { ManualOverrides, SafeTransaction } from "../types.ts";
5
+ export declare function executeManualTransactions(signer: RelayerSigner, safeContractConfig: SafeContractConfig, transactions: SafeTransaction[], overrides: ManualOverrides): Promise<ManualTransactionResponse>;
@@ -0,0 +1,49 @@
1
+ import { encodeFunctionData, encodePacked, hexToBigInt, prepareEncodeFunctionData, zeroAddress, } from "viem";
2
+ import { safeAbi } from "../abis/index.js";
3
+ import { aggregateTransaction, deriveSafe } from "../builder/index.js";
4
+ import { ManualTransactionResponse } from "../response/index.js";
5
+ const safeExecTransaction = prepareEncodeFunctionData({
6
+ abi: safeAbi,
7
+ functionName: "execTransaction",
8
+ });
9
+ export async function executeManualTransactions(signer, safeContractConfig, transactions, overrides) {
10
+ const from = await signer.getAddress();
11
+ const aggTxn = aggregateTransaction(transactions, safeContractConfig.SafeMultisend);
12
+ const sig = encodePacked(["uint256", "uint256", "uint8"], [BigInt(hexToBigInt(from)), BigInt(0), 1]);
13
+ const safeAddress = deriveSafe(from, safeContractConfig.SafeFactory);
14
+ // calldata
15
+ const data = encodeFunctionData({
16
+ ...safeExecTransaction,
17
+ args: [
18
+ aggTxn.to,
19
+ aggTxn.value,
20
+ aggTxn.data,
21
+ aggTxn.operation,
22
+ 0,
23
+ 0,
24
+ 0,
25
+ zeroAddress,
26
+ zeroAddress,
27
+ sig,
28
+ ],
29
+ });
30
+ if (overrides.gasLimit === undefined) {
31
+ const gasLimit = await signer.estimateGas({
32
+ to: safeAddress,
33
+ data: data,
34
+ from: from,
35
+ });
36
+ console.log(`Estimated gas Limit: ${gasLimit}`);
37
+ overrides.gasLimit = gasLimit;
38
+ }
39
+ const txHash = await signer.sendTransaction({
40
+ data: data,
41
+ to: safeAddress,
42
+ gasPrice: overrides.gasPrice,
43
+ gasLimit: overrides.gasLimit,
44
+ });
45
+ const waitFunc = (txHash) => {
46
+ return signer.waitTillMined(txHash);
47
+ };
48
+ return new ManualTransactionResponse(txHash, waitFunc);
49
+ }
@@ -0,0 +1,21 @@
1
+ import type { RelayClient } from "../client.ts";
2
+ import { type IManualTransactionResponse, type RelayerTransaction, type RelayerTransactionResponse } from "../types.ts";
3
+ export declare class ClientRelayerTransactionResponse implements RelayerTransactionResponse {
4
+ readonly client: RelayClient;
5
+ readonly transactionID: string;
6
+ readonly transactionHash: string;
7
+ readonly hash: string;
8
+ readonly state: string;
9
+ constructor(transactionID: string, state: string, transactionHash: string, client: RelayClient);
10
+ getTransaction(): Promise<RelayerTransaction[]>;
11
+ wait(): Promise<RelayerTransaction | undefined>;
12
+ }
13
+ type WaitUntilMinedFunction = (transactionHash: string) => Promise<any>;
14
+ export declare class ManualTransactionResponse implements IManualTransactionResponse {
15
+ readonly hash: string;
16
+ readonly transactionHash: string;
17
+ private waitTillMined;
18
+ constructor(transactionHash: string, waitTillMinedFunc: WaitUntilMinedFunction);
19
+ wait(): Promise<any>;
20
+ }
21
+ export {};
@@ -0,0 +1,34 @@
1
+ import { RelayerTransactionState, } from "../types.js";
2
+ export class ClientRelayerTransactionResponse {
3
+ client;
4
+ transactionID;
5
+ transactionHash;
6
+ hash;
7
+ state;
8
+ constructor(transactionID, state, transactionHash, client) {
9
+ this.transactionID = transactionID;
10
+ this.state = state;
11
+ this.transactionHash = transactionHash;
12
+ this.hash = transactionHash;
13
+ this.client = client;
14
+ }
15
+ async getTransaction() {
16
+ return this.client.getTransaction(this.transactionID);
17
+ }
18
+ async wait() {
19
+ return this.client.pollUntilState(this.transactionID, [RelayerTransactionState.STATE_MINED, RelayerTransactionState.STATE_CONFIRMED], RelayerTransactionState.STATE_FAILED, 30);
20
+ }
21
+ }
22
+ export class ManualTransactionResponse {
23
+ hash;
24
+ transactionHash;
25
+ waitTillMined;
26
+ constructor(transactionHash, waitTillMinedFunc) {
27
+ this.transactionHash = transactionHash;
28
+ this.hash = transactionHash;
29
+ this.waitTillMined = waitTillMinedFunc;
30
+ }
31
+ async wait() {
32
+ return this.waitTillMined(this.hash);
33
+ }
34
+ }
@@ -0,0 +1,26 @@
1
+ import { type WalletClient } from "viem";
2
+ type TypedDataDomain = Record<string, unknown>;
3
+ type TypedDataTypes = Record<string, Array<{
4
+ name: string;
5
+ type: string;
6
+ }>>;
7
+ type TypedDataValue = Record<string, unknown>;
8
+ export interface Transaction {
9
+ from?: string;
10
+ to?: string;
11
+ nonce?: number;
12
+ gasLimit?: bigint;
13
+ gasPrice?: bigint;
14
+ data?: string;
15
+ value?: bigint;
16
+ }
17
+ export interface RelayerSigner {
18
+ signMessage(message: string): Promise<string>;
19
+ signTypedData(domain: TypedDataDomain, types: TypedDataTypes, value: TypedDataValue, primaryType?: string): Promise<string>;
20
+ getAddress(): Promise<string>;
21
+ estimateGas(tx: Transaction): Promise<bigint>;
22
+ sendTransaction(tx: Transaction): Promise<string>;
23
+ waitTillMined(txHash: string): Promise<unknown>;
24
+ }
25
+ export declare function createViemSigner(chainId: number, walletClient: WalletClient): RelayerSigner;
26
+ export {};
@@ -0,0 +1,109 @@
1
+ import { createPublicClient, toBytes, } from "viem";
2
+ import { polygon, polygonAmoy } from "viem/chains";
3
+ function chainIdToChain(chainId) {
4
+ switch (chainId) {
5
+ case 137:
6
+ return polygon;
7
+ case 80002:
8
+ return polygonAmoy;
9
+ default:
10
+ throw new Error(`unsupported chainId ${chainId}`);
11
+ }
12
+ }
13
+ async function getWalletClientAddress(walletClient) {
14
+ const accountAddress = walletClient.account?.address;
15
+ if (typeof accountAddress === "string" && accountAddress.length > 0) {
16
+ return accountAddress;
17
+ }
18
+ try {
19
+ const [address] = await walletClient.getAddresses();
20
+ if (typeof address === "string" && address.length > 0) {
21
+ return address;
22
+ }
23
+ }
24
+ catch {
25
+ // Fall back to requestAddresses for wallets that require user interaction.
26
+ }
27
+ const [requestedAddress] = await walletClient.requestAddresses();
28
+ if (typeof requestedAddress === "string" && requestedAddress.length > 0) {
29
+ return requestedAddress;
30
+ }
31
+ throw new Error("wallet client is missing account address");
32
+ }
33
+ async function getWalletClientAccount(walletClient) {
34
+ if (walletClient.account !== undefined) {
35
+ return walletClient.account;
36
+ }
37
+ return getWalletClientAddress(walletClient);
38
+ }
39
+ export function createViemSigner(chainId, walletClient) {
40
+ if (walletClient.chain !== undefined && walletClient.chain.id !== chainId) {
41
+ throw new Error("wallet client chain id does not match chain id");
42
+ }
43
+ const chain = walletClient.chain ?? chainIdToChain(chainId);
44
+ const walletTransport = walletClient.transport;
45
+ const transport = () => ({
46
+ config: walletTransport.config,
47
+ name: walletTransport.name,
48
+ request: walletTransport.request,
49
+ type: walletTransport.type,
50
+ value: walletTransport.value,
51
+ });
52
+ const publicClient = createPublicClient({
53
+ chain,
54
+ transport,
55
+ });
56
+ return {
57
+ async signMessage(message) {
58
+ const account = await getWalletClientAccount(walletClient);
59
+ return walletClient.signMessage({
60
+ account,
61
+ message: { raw: toBytes(message) },
62
+ });
63
+ },
64
+ async signTypedData(domain, types, value, primaryType) {
65
+ if (primaryType === undefined) {
66
+ throw new Error("primaryType is required in viem signers");
67
+ }
68
+ const account = await getWalletClientAccount(walletClient);
69
+ return walletClient.signTypedData({
70
+ account,
71
+ domain,
72
+ types,
73
+ primaryType,
74
+ message: value,
75
+ });
76
+ },
77
+ async getAddress() {
78
+ return getWalletClientAddress(walletClient);
79
+ },
80
+ async estimateGas(tx) {
81
+ const account = tx.from ?? (await getWalletClientAddress(walletClient));
82
+ return publicClient.estimateGas({
83
+ account: account,
84
+ to: tx.to,
85
+ data: tx.data,
86
+ value: tx.value,
87
+ nonce: tx.nonce,
88
+ });
89
+ },
90
+ async sendTransaction(tx) {
91
+ const account = await getWalletClientAccount(walletClient);
92
+ return walletClient.sendTransaction({
93
+ account,
94
+ chain,
95
+ to: tx.to,
96
+ data: tx.data,
97
+ value: tx.value,
98
+ gas: tx.gasLimit,
99
+ gasPrice: tx.gasPrice,
100
+ nonce: tx.nonce,
101
+ });
102
+ },
103
+ async waitTillMined(txHash) {
104
+ return publicClient.waitForTransactionReceipt({
105
+ hash: txHash,
106
+ });
107
+ },
108
+ };
109
+ }