kentucky-signer-viem 0.1.3 → 0.1.5
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/README.md +262 -26
- package/dist/index.d.mts +376 -10
- package/dist/index.d.ts +376 -10
- package/dist/index.js +281 -25
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +282 -26
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +465 -3
- package/dist/react/index.d.ts +465 -3
- package/dist/react/index.js +390 -25
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +391 -26
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/account.ts +183 -23
- package/src/client.ts +4 -5
- package/src/index.ts +32 -0
- package/src/intent.ts +167 -0
- package/src/react/index.ts +33 -0
- package/src/react/relayer-hooks.ts +318 -0
- package/src/relayer-client.ts +305 -0
- package/src/secure-client.ts +2 -2
- package/src/types.ts +4 -3
package/dist/react/index.mjs
CHANGED
|
@@ -153,9 +153,9 @@ var KentuckySignerClient = class {
|
|
|
153
153
|
/**
|
|
154
154
|
* Sign an EVM transaction hash
|
|
155
155
|
*
|
|
156
|
-
* @param request - Sign request with tx_hash
|
|
156
|
+
* @param request - Sign request with tx_hash
|
|
157
157
|
* @param token - JWT token
|
|
158
|
-
* @returns Signature response with r, s, v components
|
|
158
|
+
* @returns Signature response with r, s, v components (v is always 27 or 28)
|
|
159
159
|
*/
|
|
160
160
|
async signEvmTransaction(request, token) {
|
|
161
161
|
return this.request("/api/sign/evm", {
|
|
@@ -170,13 +170,12 @@ var KentuckySignerClient = class {
|
|
|
170
170
|
* Convenience method that wraps signEvmTransaction.
|
|
171
171
|
*
|
|
172
172
|
* @param hash - 32-byte hash to sign (hex encoded with 0x prefix)
|
|
173
|
-
* @param chainId - Chain ID
|
|
174
173
|
* @param token - JWT token
|
|
175
174
|
* @returns Full signature (hex encoded with 0x prefix)
|
|
176
175
|
*/
|
|
177
|
-
async signHash(hash,
|
|
176
|
+
async signHash(hash, token) {
|
|
178
177
|
const response = await this.signEvmTransaction(
|
|
179
|
-
{ tx_hash: hash
|
|
178
|
+
{ tx_hash: hash },
|
|
180
179
|
token
|
|
181
180
|
);
|
|
182
181
|
return response.signature.full;
|
|
@@ -1010,9 +1009,9 @@ var SecureKentuckySignerClient = class {
|
|
|
1010
1009
|
/**
|
|
1011
1010
|
* Sign a raw hash for EVM (signed request)
|
|
1012
1011
|
*/
|
|
1013
|
-
async signHash(hash,
|
|
1012
|
+
async signHash(hash, token) {
|
|
1014
1013
|
const response = await this.signEvmTransaction(
|
|
1015
|
-
{ tx_hash: hash
|
|
1014
|
+
{ tx_hash: hash },
|
|
1016
1015
|
token
|
|
1017
1016
|
);
|
|
1018
1017
|
return response.signature.full;
|
|
@@ -1234,9 +1233,21 @@ import {
|
|
|
1234
1233
|
hashMessage,
|
|
1235
1234
|
hashTypedData,
|
|
1236
1235
|
keccak256,
|
|
1237
|
-
serializeTransaction
|
|
1236
|
+
serializeTransaction,
|
|
1237
|
+
toRlp,
|
|
1238
|
+
concat,
|
|
1239
|
+
numberToHex
|
|
1238
1240
|
} from "viem";
|
|
1239
1241
|
import { toAccount } from "viem/accounts";
|
|
1242
|
+
var EIP7702_MAGIC = "0x05";
|
|
1243
|
+
function hashAuthorization(params) {
|
|
1244
|
+
const rlpEncoded = toRlp([
|
|
1245
|
+
params.chainId === 0 ? "0x" : numberToHex(params.chainId),
|
|
1246
|
+
params.contractAddress,
|
|
1247
|
+
params.nonce === 0n ? "0x" : numberToHex(params.nonce)
|
|
1248
|
+
]);
|
|
1249
|
+
return keccak256(concat([EIP7702_MAGIC, rlpEncoded]));
|
|
1250
|
+
}
|
|
1240
1251
|
function createKentuckySignerAccount(options) {
|
|
1241
1252
|
const { config, defaultChainId = 1, onSessionExpired, secureClient, on2FARequired } = options;
|
|
1242
1253
|
let session = options.session;
|
|
@@ -1255,14 +1266,17 @@ function createKentuckySignerAccount(options) {
|
|
|
1255
1266
|
}
|
|
1256
1267
|
return session.token;
|
|
1257
1268
|
}
|
|
1258
|
-
|
|
1269
|
+
function ensureHexPrefix(value) {
|
|
1270
|
+
return value.startsWith("0x") ? value : `0x${value}`;
|
|
1271
|
+
}
|
|
1272
|
+
async function signHash(hash) {
|
|
1259
1273
|
const token = await getToken();
|
|
1260
1274
|
try {
|
|
1261
1275
|
const response = await client.signEvmTransaction(
|
|
1262
|
-
{ tx_hash: hash
|
|
1276
|
+
{ tx_hash: hash },
|
|
1263
1277
|
token
|
|
1264
1278
|
);
|
|
1265
|
-
return response.signature.full;
|
|
1279
|
+
return ensureHexPrefix(response.signature.full);
|
|
1266
1280
|
} catch (err) {
|
|
1267
1281
|
if (err instanceof KentuckySignerError && err.code === "2FA_REQUIRED" && on2FARequired) {
|
|
1268
1282
|
const totpRequired = err.message.includes("TOTP") || (err.details?.includes("totp_code") ?? false);
|
|
@@ -1273,24 +1287,24 @@ function createKentuckySignerAccount(options) {
|
|
|
1273
1287
|
throw new KentuckySignerError("2FA verification cancelled", "2FA_CANCELLED", "User cancelled 2FA input");
|
|
1274
1288
|
}
|
|
1275
1289
|
const response = await client.signEvmTransactionWith2FA(
|
|
1276
|
-
{ tx_hash: hash,
|
|
1290
|
+
{ tx_hash: hash, totp_code: codes.totpCode, pin: codes.pin },
|
|
1277
1291
|
token
|
|
1278
1292
|
);
|
|
1279
|
-
return response.signature.full;
|
|
1293
|
+
return ensureHexPrefix(response.signature.full);
|
|
1280
1294
|
}
|
|
1281
1295
|
throw err;
|
|
1282
1296
|
}
|
|
1283
1297
|
}
|
|
1284
|
-
async function signHashWithComponents(hash
|
|
1298
|
+
async function signHashWithComponents(hash) {
|
|
1285
1299
|
const token = await getToken();
|
|
1286
1300
|
try {
|
|
1287
1301
|
const response = await client.signEvmTransaction(
|
|
1288
|
-
{ tx_hash: hash
|
|
1302
|
+
{ tx_hash: hash },
|
|
1289
1303
|
token
|
|
1290
1304
|
);
|
|
1291
1305
|
return {
|
|
1292
|
-
r: response.signature.r,
|
|
1293
|
-
s: response.signature.s,
|
|
1306
|
+
r: ensureHexPrefix(response.signature.r),
|
|
1307
|
+
s: ensureHexPrefix(response.signature.s),
|
|
1294
1308
|
v: response.signature.v
|
|
1295
1309
|
};
|
|
1296
1310
|
} catch (err) {
|
|
@@ -1303,12 +1317,12 @@ function createKentuckySignerAccount(options) {
|
|
|
1303
1317
|
throw new KentuckySignerError("2FA verification cancelled", "2FA_CANCELLED", "User cancelled 2FA input");
|
|
1304
1318
|
}
|
|
1305
1319
|
const response = await client.signEvmTransactionWith2FA(
|
|
1306
|
-
{ tx_hash: hash,
|
|
1320
|
+
{ tx_hash: hash, totp_code: codes.totpCode, pin: codes.pin },
|
|
1307
1321
|
token
|
|
1308
1322
|
);
|
|
1309
1323
|
return {
|
|
1310
|
-
r: response.signature.r,
|
|
1311
|
-
s: response.signature.s,
|
|
1324
|
+
r: ensureHexPrefix(response.signature.r),
|
|
1325
|
+
s: ensureHexPrefix(response.signature.s),
|
|
1312
1326
|
v: response.signature.v
|
|
1313
1327
|
};
|
|
1314
1328
|
}
|
|
@@ -1324,29 +1338,36 @@ function createKentuckySignerAccount(options) {
|
|
|
1324
1338
|
*/
|
|
1325
1339
|
async signMessage({ message }) {
|
|
1326
1340
|
const messageHash = hashMessage(message);
|
|
1327
|
-
return signHash(messageHash
|
|
1341
|
+
return signHash(messageHash);
|
|
1328
1342
|
},
|
|
1329
1343
|
/**
|
|
1330
1344
|
* Sign a transaction
|
|
1331
1345
|
*
|
|
1332
1346
|
* Serializes the transaction, hashes it, signs via Kentucky Signer,
|
|
1333
1347
|
* and returns the signed serialized transaction.
|
|
1348
|
+
*
|
|
1349
|
+
* For legacy transactions, applies EIP-155 encoding (v = chainId * 2 + 35 + recoveryId)
|
|
1350
|
+
* For modern transactions (EIP-1559, EIP-2930, etc.), uses yParity (0 or 1)
|
|
1334
1351
|
*/
|
|
1335
1352
|
async signTransaction(transaction) {
|
|
1336
1353
|
const chainId = transaction.chainId ?? defaultChainId;
|
|
1337
1354
|
const serializedUnsigned = serializeTransaction(transaction);
|
|
1338
1355
|
const txHash = keccak256(serializedUnsigned);
|
|
1339
|
-
const { r, s, v } = await signHashWithComponents(txHash
|
|
1356
|
+
const { r, s, v } = await signHashWithComponents(txHash);
|
|
1357
|
+
const recoveryId = v - 27;
|
|
1358
|
+
let signatureV;
|
|
1340
1359
|
let yParity;
|
|
1341
1360
|
if (transaction.type === "eip1559" || transaction.type === "eip2930" || transaction.type === "eip4844" || transaction.type === "eip7702") {
|
|
1342
|
-
yParity =
|
|
1361
|
+
yParity = recoveryId;
|
|
1362
|
+
signatureV = BigInt(yParity);
|
|
1343
1363
|
} else {
|
|
1344
|
-
|
|
1364
|
+
signatureV = BigInt(chainId * 2 + 35 + recoveryId);
|
|
1365
|
+
yParity = recoveryId;
|
|
1345
1366
|
}
|
|
1346
1367
|
const serializedSigned = serializeTransaction(transaction, {
|
|
1347
1368
|
r,
|
|
1348
1369
|
s,
|
|
1349
|
-
v:
|
|
1370
|
+
v: signatureV,
|
|
1350
1371
|
yParity
|
|
1351
1372
|
});
|
|
1352
1373
|
return serializedSigned;
|
|
@@ -1356,7 +1377,7 @@ function createKentuckySignerAccount(options) {
|
|
|
1356
1377
|
*/
|
|
1357
1378
|
async signTypedData(typedData) {
|
|
1358
1379
|
const hash = hashTypedData(typedData);
|
|
1359
|
-
return signHash(hash
|
|
1380
|
+
return signHash(hash);
|
|
1360
1381
|
}
|
|
1361
1382
|
});
|
|
1362
1383
|
account.source = "kentuckySigner";
|
|
@@ -1369,6 +1390,25 @@ function createKentuckySignerAccount(options) {
|
|
|
1369
1390
|
account.address = newSession.evmAddress;
|
|
1370
1391
|
}
|
|
1371
1392
|
};
|
|
1393
|
+
account.sign7702Authorization = async (params, currentNonce) => {
|
|
1394
|
+
const authNonce = params.executor === "self" ? currentNonce + 1n : params.nonce ?? currentNonce;
|
|
1395
|
+
const chainId = params.chainId ?? defaultChainId;
|
|
1396
|
+
const authHash = hashAuthorization({
|
|
1397
|
+
contractAddress: params.contractAddress,
|
|
1398
|
+
chainId,
|
|
1399
|
+
nonce: authNonce
|
|
1400
|
+
});
|
|
1401
|
+
const { r, s, v } = await signHashWithComponents(authHash);
|
|
1402
|
+
const yParity = v - 27;
|
|
1403
|
+
return {
|
|
1404
|
+
chainId,
|
|
1405
|
+
contractAddress: params.contractAddress,
|
|
1406
|
+
nonce: authNonce,
|
|
1407
|
+
yParity,
|
|
1408
|
+
r,
|
|
1409
|
+
s
|
|
1410
|
+
};
|
|
1411
|
+
};
|
|
1372
1412
|
return account;
|
|
1373
1413
|
}
|
|
1374
1414
|
|
|
@@ -1890,16 +1930,341 @@ function useAddress() {
|
|
|
1890
1930
|
const { account } = useKentuckySignerContext();
|
|
1891
1931
|
return account?.address;
|
|
1892
1932
|
}
|
|
1933
|
+
|
|
1934
|
+
// src/react/relayer-hooks.ts
|
|
1935
|
+
import { useState as useState3, useCallback as useCallback3, useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
1936
|
+
function useRelayIntent(client) {
|
|
1937
|
+
const [isRelaying, setIsRelaying] = useState3(false);
|
|
1938
|
+
const [response, setResponse] = useState3(null);
|
|
1939
|
+
const [error, setError] = useState3(null);
|
|
1940
|
+
const relay = useCallback3(
|
|
1941
|
+
async (chainId, accountAddress, signedIntent, paymentMode, authorization) => {
|
|
1942
|
+
setIsRelaying(true);
|
|
1943
|
+
setError(null);
|
|
1944
|
+
try {
|
|
1945
|
+
const result = await client.relay(chainId, accountAddress, signedIntent, paymentMode, authorization);
|
|
1946
|
+
setResponse(result);
|
|
1947
|
+
return result;
|
|
1948
|
+
} catch (err) {
|
|
1949
|
+
const error2 = err instanceof Error ? err : new Error("Relay failed");
|
|
1950
|
+
setError(error2);
|
|
1951
|
+
return { success: false, error: error2.message };
|
|
1952
|
+
} finally {
|
|
1953
|
+
setIsRelaying(false);
|
|
1954
|
+
}
|
|
1955
|
+
},
|
|
1956
|
+
[client]
|
|
1957
|
+
);
|
|
1958
|
+
const reset = useCallback3(() => {
|
|
1959
|
+
setResponse(null);
|
|
1960
|
+
setError(null);
|
|
1961
|
+
}, []);
|
|
1962
|
+
return { relay, isRelaying, response, error, reset };
|
|
1963
|
+
}
|
|
1964
|
+
function useTransactionStatus(client, chainId, txHash, pollInterval = 3e3) {
|
|
1965
|
+
const [status, setStatus] = useState3(null);
|
|
1966
|
+
const [statusResponse, setStatusResponse] = useState3(null);
|
|
1967
|
+
const [isLoading, setIsLoading] = useState3(false);
|
|
1968
|
+
const [error, setError] = useState3(null);
|
|
1969
|
+
const intervalRef = useRef2(null);
|
|
1970
|
+
const fetchStatus = useCallback3(async () => {
|
|
1971
|
+
if (!txHash) return;
|
|
1972
|
+
setIsLoading(true);
|
|
1973
|
+
try {
|
|
1974
|
+
const response = await client.getStatus(chainId, txHash);
|
|
1975
|
+
setStatusResponse(response);
|
|
1976
|
+
setStatus(response.status);
|
|
1977
|
+
setError(null);
|
|
1978
|
+
if (response.status === "confirmed" || response.status === "failed") {
|
|
1979
|
+
if (intervalRef.current) {
|
|
1980
|
+
clearInterval(intervalRef.current);
|
|
1981
|
+
intervalRef.current = null;
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
} catch (err) {
|
|
1985
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch status"));
|
|
1986
|
+
} finally {
|
|
1987
|
+
setIsLoading(false);
|
|
1988
|
+
}
|
|
1989
|
+
}, [client, chainId, txHash]);
|
|
1990
|
+
useEffect2(() => {
|
|
1991
|
+
if (!txHash) {
|
|
1992
|
+
setStatus(null);
|
|
1993
|
+
setStatusResponse(null);
|
|
1994
|
+
return;
|
|
1995
|
+
}
|
|
1996
|
+
fetchStatus();
|
|
1997
|
+
intervalRef.current = setInterval(fetchStatus, pollInterval);
|
|
1998
|
+
return () => {
|
|
1999
|
+
if (intervalRef.current) {
|
|
2000
|
+
clearInterval(intervalRef.current);
|
|
2001
|
+
intervalRef.current = null;
|
|
2002
|
+
}
|
|
2003
|
+
};
|
|
2004
|
+
}, [txHash, pollInterval, fetchStatus]);
|
|
2005
|
+
return { status, statusResponse, isLoading, error, refresh: fetchStatus };
|
|
2006
|
+
}
|
|
2007
|
+
function useEstimate(client) {
|
|
2008
|
+
const [estimateResponse, setEstimateResponse] = useState3(null);
|
|
2009
|
+
const [isEstimating, setIsEstimating] = useState3(false);
|
|
2010
|
+
const [error, setError] = useState3(null);
|
|
2011
|
+
const estimate = useCallback3(
|
|
2012
|
+
async (chainId, accountAddress, intent) => {
|
|
2013
|
+
setIsEstimating(true);
|
|
2014
|
+
setError(null);
|
|
2015
|
+
try {
|
|
2016
|
+
const response = await client.estimate(chainId, accountAddress, intent);
|
|
2017
|
+
setEstimateResponse(response);
|
|
2018
|
+
return response;
|
|
2019
|
+
} catch (err) {
|
|
2020
|
+
const error2 = err instanceof Error ? err : new Error("Estimate failed");
|
|
2021
|
+
setError(error2);
|
|
2022
|
+
return null;
|
|
2023
|
+
} finally {
|
|
2024
|
+
setIsEstimating(false);
|
|
2025
|
+
}
|
|
2026
|
+
},
|
|
2027
|
+
[client]
|
|
2028
|
+
);
|
|
2029
|
+
return { estimate, estimateResponse, isEstimating, error };
|
|
2030
|
+
}
|
|
2031
|
+
function useNonce(client, chainId, address) {
|
|
2032
|
+
const [nonce, setNonce] = useState3(null);
|
|
2033
|
+
const [isLoading, setIsLoading] = useState3(false);
|
|
2034
|
+
const [error, setError] = useState3(null);
|
|
2035
|
+
const fetchNonce = useCallback3(async () => {
|
|
2036
|
+
if (!address) return;
|
|
2037
|
+
setIsLoading(true);
|
|
2038
|
+
try {
|
|
2039
|
+
const result = await client.getNonce(chainId, address);
|
|
2040
|
+
setNonce(result);
|
|
2041
|
+
setError(null);
|
|
2042
|
+
} catch (err) {
|
|
2043
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch nonce"));
|
|
2044
|
+
} finally {
|
|
2045
|
+
setIsLoading(false);
|
|
2046
|
+
}
|
|
2047
|
+
}, [client, chainId, address]);
|
|
2048
|
+
useEffect2(() => {
|
|
2049
|
+
if (address) {
|
|
2050
|
+
fetchNonce();
|
|
2051
|
+
} else {
|
|
2052
|
+
setNonce(null);
|
|
2053
|
+
}
|
|
2054
|
+
}, [address, fetchNonce]);
|
|
2055
|
+
return { nonce, isLoading, error, refresh: fetchNonce };
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
// src/relayer-client.ts
|
|
2059
|
+
var RelayerClient = class {
|
|
2060
|
+
constructor(options) {
|
|
2061
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
2062
|
+
this.timeout = options.timeout ?? 3e4;
|
|
2063
|
+
}
|
|
2064
|
+
/**
|
|
2065
|
+
* Check if the relayer is healthy
|
|
2066
|
+
*/
|
|
2067
|
+
async health() {
|
|
2068
|
+
const response = await this.fetch("/health");
|
|
2069
|
+
return response;
|
|
2070
|
+
}
|
|
2071
|
+
/**
|
|
2072
|
+
* Get the current nonce for an account
|
|
2073
|
+
*
|
|
2074
|
+
* @param chainId - Chain ID
|
|
2075
|
+
* @param address - Account address
|
|
2076
|
+
* @returns Current nonce as bigint
|
|
2077
|
+
*/
|
|
2078
|
+
async getNonce(chainId, address) {
|
|
2079
|
+
const response = await this.fetch(`/nonce/${chainId}/${address}`);
|
|
2080
|
+
return BigInt(response.nonce);
|
|
2081
|
+
}
|
|
2082
|
+
/**
|
|
2083
|
+
* Estimate gas and fees for an intent
|
|
2084
|
+
*
|
|
2085
|
+
* @param chainId - Chain ID
|
|
2086
|
+
* @param accountAddress - Account address (the delegated EOA)
|
|
2087
|
+
* @param intent - Execution intent
|
|
2088
|
+
* @returns Estimate response
|
|
2089
|
+
*/
|
|
2090
|
+
async estimate(chainId, accountAddress, intent) {
|
|
2091
|
+
const response = await this.fetch("/estimate", {
|
|
2092
|
+
method: "POST",
|
|
2093
|
+
body: JSON.stringify({
|
|
2094
|
+
chainId,
|
|
2095
|
+
accountAddress,
|
|
2096
|
+
intent: {
|
|
2097
|
+
nonce: intent.nonce.toString(),
|
|
2098
|
+
deadline: intent.deadline.toString(),
|
|
2099
|
+
target: intent.target,
|
|
2100
|
+
value: intent.value.toString(),
|
|
2101
|
+
data: intent.data
|
|
2102
|
+
}
|
|
2103
|
+
})
|
|
2104
|
+
});
|
|
2105
|
+
return response;
|
|
2106
|
+
}
|
|
2107
|
+
/**
|
|
2108
|
+
* Relay a signed intent
|
|
2109
|
+
*
|
|
2110
|
+
* @param chainId - Chain ID
|
|
2111
|
+
* @param accountAddress - Account address (the delegated EOA)
|
|
2112
|
+
* @param signedIntent - Signed execution intent
|
|
2113
|
+
* @param paymentMode - Payment mode ('sponsored' or { token: Address })
|
|
2114
|
+
* @param authorization - Optional EIP-7702 authorization for gasless onboarding
|
|
2115
|
+
* @returns Relay response with transaction hash
|
|
2116
|
+
*
|
|
2117
|
+
* @example Gasless onboarding (delegate + execute in one tx)
|
|
2118
|
+
* ```typescript
|
|
2119
|
+
* // Get current nonce for authorization
|
|
2120
|
+
* const txNonce = await publicClient.getTransactionCount({ address: accountAddress })
|
|
2121
|
+
*
|
|
2122
|
+
* // Sign EIP-7702 authorization
|
|
2123
|
+
* const authorization = await account.sign7702Authorization({
|
|
2124
|
+
* contractAddress: delegateAddress,
|
|
2125
|
+
* chainId: 42161,
|
|
2126
|
+
* }, txNonce)
|
|
2127
|
+
*
|
|
2128
|
+
* // Relay with authorization
|
|
2129
|
+
* const result = await relayer.relay(
|
|
2130
|
+
* 42161,
|
|
2131
|
+
* accountAddress,
|
|
2132
|
+
* signedIntent,
|
|
2133
|
+
* 'sponsored',
|
|
2134
|
+
* authorization
|
|
2135
|
+
* )
|
|
2136
|
+
* ```
|
|
2137
|
+
*/
|
|
2138
|
+
async relay(chainId, accountAddress, signedIntent, paymentMode, authorization) {
|
|
2139
|
+
const body = {
|
|
2140
|
+
chainId,
|
|
2141
|
+
accountAddress,
|
|
2142
|
+
intent: {
|
|
2143
|
+
nonce: signedIntent.intent.nonce.toString(),
|
|
2144
|
+
deadline: signedIntent.intent.deadline.toString(),
|
|
2145
|
+
target: signedIntent.intent.target,
|
|
2146
|
+
value: signedIntent.intent.value.toString(),
|
|
2147
|
+
data: signedIntent.intent.data
|
|
2148
|
+
},
|
|
2149
|
+
ownerSignature: signedIntent.signature,
|
|
2150
|
+
paymentMode
|
|
2151
|
+
};
|
|
2152
|
+
if (authorization) {
|
|
2153
|
+
body.authorization = {
|
|
2154
|
+
chainId: authorization.chainId,
|
|
2155
|
+
contractAddress: authorization.contractAddress,
|
|
2156
|
+
nonce: authorization.nonce.toString(),
|
|
2157
|
+
yParity: authorization.yParity,
|
|
2158
|
+
r: authorization.r,
|
|
2159
|
+
s: authorization.s
|
|
2160
|
+
};
|
|
2161
|
+
}
|
|
2162
|
+
const response = await this.fetch("/relay", {
|
|
2163
|
+
method: "POST",
|
|
2164
|
+
body: JSON.stringify(body)
|
|
2165
|
+
});
|
|
2166
|
+
return response;
|
|
2167
|
+
}
|
|
2168
|
+
/**
|
|
2169
|
+
* Get transaction status
|
|
2170
|
+
*
|
|
2171
|
+
* @param chainId - Chain ID
|
|
2172
|
+
* @param txHash - Transaction hash
|
|
2173
|
+
* @returns Status response
|
|
2174
|
+
*/
|
|
2175
|
+
async getStatus(chainId, txHash) {
|
|
2176
|
+
const response = await this.fetch(`/status/${chainId}/${txHash}`);
|
|
2177
|
+
return response;
|
|
2178
|
+
}
|
|
2179
|
+
/**
|
|
2180
|
+
* Make a fetch request to the relayer API
|
|
2181
|
+
*/
|
|
2182
|
+
async fetch(path, options) {
|
|
2183
|
+
const controller = new AbortController();
|
|
2184
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
2185
|
+
try {
|
|
2186
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
2187
|
+
...options,
|
|
2188
|
+
headers: {
|
|
2189
|
+
"Content-Type": "application/json",
|
|
2190
|
+
...options?.headers
|
|
2191
|
+
},
|
|
2192
|
+
signal: controller.signal
|
|
2193
|
+
});
|
|
2194
|
+
const data = await response.json();
|
|
2195
|
+
if (!response.ok) {
|
|
2196
|
+
throw new Error(data.error || `Request failed: ${response.status}`);
|
|
2197
|
+
}
|
|
2198
|
+
return data;
|
|
2199
|
+
} finally {
|
|
2200
|
+
clearTimeout(timeoutId);
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
};
|
|
2204
|
+
function createRelayerClient(baseUrl) {
|
|
2205
|
+
return new RelayerClient({ baseUrl });
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
// src/intent.ts
|
|
2209
|
+
import {
|
|
2210
|
+
keccak256 as keccak2562,
|
|
2211
|
+
encodeAbiParameters,
|
|
2212
|
+
parseAbiParameters,
|
|
2213
|
+
encodePacked
|
|
2214
|
+
} from "viem";
|
|
2215
|
+
var INTENT_TYPEHASH = keccak2562(
|
|
2216
|
+
encodePacked(
|
|
2217
|
+
["string"],
|
|
2218
|
+
["ExecutionIntent(uint256 nonce,uint256 deadline,address target,uint256 value,bytes data)"]
|
|
2219
|
+
)
|
|
2220
|
+
);
|
|
2221
|
+
function createExecutionIntent(params) {
|
|
2222
|
+
return {
|
|
2223
|
+
nonce: params.nonce,
|
|
2224
|
+
deadline: params.deadline ?? BigInt(Math.floor(Date.now() / 1e3) + 3600),
|
|
2225
|
+
// 1 hour default
|
|
2226
|
+
target: params.target,
|
|
2227
|
+
value: params.value ?? 0n,
|
|
2228
|
+
data: params.data ?? "0x"
|
|
2229
|
+
};
|
|
2230
|
+
}
|
|
2231
|
+
function hashIntent(intent) {
|
|
2232
|
+
const dataHash = keccak2562(intent.data);
|
|
2233
|
+
return keccak2562(
|
|
2234
|
+
encodeAbiParameters(
|
|
2235
|
+
parseAbiParameters("bytes32, uint256, uint256, address, uint256, bytes32"),
|
|
2236
|
+
[INTENT_TYPEHASH, intent.nonce, intent.deadline, intent.target, intent.value, dataHash]
|
|
2237
|
+
)
|
|
2238
|
+
);
|
|
2239
|
+
}
|
|
2240
|
+
async function signIntent(account, intent) {
|
|
2241
|
+
const intentHash = hashIntent(intent);
|
|
2242
|
+
const signature = await account.signMessage({
|
|
2243
|
+
message: { raw: intentHash }
|
|
2244
|
+
});
|
|
2245
|
+
return {
|
|
2246
|
+
intent,
|
|
2247
|
+
signature
|
|
2248
|
+
};
|
|
2249
|
+
}
|
|
1893
2250
|
export {
|
|
1894
2251
|
KentuckySignerProvider,
|
|
2252
|
+
RelayerClient,
|
|
2253
|
+
createExecutionIntent,
|
|
2254
|
+
createRelayerClient,
|
|
2255
|
+
signIntent,
|
|
1895
2256
|
useAddress,
|
|
2257
|
+
useEstimate,
|
|
1896
2258
|
useIsReady,
|
|
1897
2259
|
useKentuckySigner,
|
|
1898
2260
|
useKentuckySignerAccount,
|
|
1899
2261
|
useKentuckySignerContext,
|
|
2262
|
+
useNonce,
|
|
1900
2263
|
usePasskeyAuth,
|
|
2264
|
+
useRelayIntent,
|
|
1901
2265
|
useSignMessage,
|
|
1902
2266
|
useSignTypedData,
|
|
2267
|
+
useTransactionStatus,
|
|
1903
2268
|
useWalletClient
|
|
1904
2269
|
};
|
|
1905
2270
|
//# sourceMappingURL=index.mjs.map
|