@lit-protocol/vincent-ability-relay-link 1.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/CHANGELOG.md +18 -0
- package/CONTRIBUTING.md +82 -0
- package/README.md +223 -0
- package/dist/CHANGELOG.md +0 -0
- package/dist/CONTRIBUTING.md +82 -0
- package/dist/README.md +223 -0
- package/dist/package.json +37 -0
- package/dist/src/generated/lit-action.js +9 -0
- package/dist/src/generated/vincent-ability-metadata.json +3 -0
- package/dist/src/generated/vincent-bundled-ability.d.ts +1440 -0
- package/dist/src/generated/vincent-bundled-ability.d.ts.map +1 -0
- package/dist/src/generated/vincent-bundled-ability.js +15 -0
- package/dist/src/generated/vincent-bundled-ability.js.map +1 -0
- package/dist/src/generated/vincent-bundled-ability.ts +13 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +29 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lib/decodeTransaction.d.ts +3 -0
- package/dist/src/lib/decodeTransaction.d.ts.map +1 -0
- package/dist/src/lib/decodeTransaction.js +48 -0
- package/dist/src/lib/decodeTransaction.js.map +1 -0
- package/dist/src/lib/helpers/crossmint.d.ts +37 -0
- package/dist/src/lib/helpers/crossmint.d.ts.map +1 -0
- package/dist/src/lib/helpers/crossmint.js +50 -0
- package/dist/src/lib/helpers/crossmint.js.map +1 -0
- package/dist/src/lib/helpers/relay-link.d.ts +71 -0
- package/dist/src/lib/helpers/relay-link.d.ts.map +1 -0
- package/dist/src/lib/helpers/relay-link.js +157 -0
- package/dist/src/lib/helpers/relay-link.js.map +1 -0
- package/dist/src/lib/helpers/safe.d.ts +52 -0
- package/dist/src/lib/helpers/safe.d.ts.map +1 -0
- package/dist/src/lib/helpers/safe.js +98 -0
- package/dist/src/lib/helpers/safe.js.map +1 -0
- package/dist/src/lib/helpers/transactionKind.d.ts +5 -0
- package/dist/src/lib/helpers/transactionKind.d.ts.map +1 -0
- package/dist/src/lib/helpers/transactionKind.js +9 -0
- package/dist/src/lib/helpers/transactionKind.js.map +1 -0
- package/dist/src/lib/helpers/zerodev.d.ts +58 -0
- package/dist/src/lib/helpers/zerodev.d.ts.map +1 -0
- package/dist/src/lib/helpers/zerodev.js +127 -0
- package/dist/src/lib/helpers/zerodev.js.map +1 -0
- package/dist/src/lib/lit-action.d.ts +2 -0
- package/dist/src/lib/lit-action.d.ts.map +1 -0
- package/dist/src/lib/lit-action.js +15 -0
- package/dist/src/lib/lit-action.js.map +1 -0
- package/dist/src/lib/validateSimulation.d.ts +3 -0
- package/dist/src/lib/validateSimulation.d.ts.map +1 -0
- package/dist/src/lib/validateSimulation.js +116 -0
- package/dist/src/lib/validateSimulation.js.map +1 -0
- package/dist/src/lib/validateTransaction.d.ts +3 -0
- package/dist/src/lib/validateTransaction.d.ts.map +1 -0
- package/dist/src/lib/validateTransaction.js +44 -0
- package/dist/src/lib/validateTransaction.js.map +1 -0
- package/dist/src/lib/vincent-ability.d.ts +1437 -0
- package/dist/src/lib/vincent-ability.d.ts.map +1 -0
- package/dist/src/lib/vincent-ability.js +15 -0
- package/dist/src/lib/vincent-ability.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.transactionsToSafeUserOp = transactionsToSafeUserOp;
|
|
4
|
+
exports.sendPermittedSafeUserOperation = sendPermittedSafeUserOperation;
|
|
5
|
+
const viem_1 = require("viem");
|
|
6
|
+
const accounts_1 = require("viem/accounts");
|
|
7
|
+
const account_abstraction_1 = require("viem/account-abstraction");
|
|
8
|
+
const permissionless_1 = require("permissionless");
|
|
9
|
+
const accounts_2 = require("permissionless/accounts");
|
|
10
|
+
const pimlico_1 = require("permissionless/clients/pimlico");
|
|
11
|
+
const safeVersion = '1.4.1';
|
|
12
|
+
const entryPoint = {
|
|
13
|
+
address: account_abstraction_1.entryPoint07Address,
|
|
14
|
+
version: '0.7',
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Create a dummy account for the PKP address.
|
|
18
|
+
* Returns dummy signatures for estimation/building.
|
|
19
|
+
*/
|
|
20
|
+
function addressToAccount(address) {
|
|
21
|
+
return (0, accounts_1.toAccount)({
|
|
22
|
+
address,
|
|
23
|
+
async signMessage() {
|
|
24
|
+
return `0x${'00'.repeat(65)}`;
|
|
25
|
+
},
|
|
26
|
+
async signTypedData() {
|
|
27
|
+
return `0x${'00'.repeat(65)}`;
|
|
28
|
+
},
|
|
29
|
+
async signTransaction() {
|
|
30
|
+
return `0x${'00'.repeat(65)}`;
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a Safe UserOp from transactions.
|
|
36
|
+
* Returns the unsigned UserOp that needs to be signed by the Vincent ability.
|
|
37
|
+
*/
|
|
38
|
+
async function transactionsToSafeUserOp({ safeAddress, permittedAddress, transactions, chain, safeRpcUrl, pimlicoRpcUrl, }) {
|
|
39
|
+
const safeTransport = (0, viem_1.http)(safeRpcUrl);
|
|
40
|
+
const pimlicoTransport = (0, viem_1.http)(pimlicoRpcUrl);
|
|
41
|
+
const publicClient = (0, viem_1.createPublicClient)({
|
|
42
|
+
chain,
|
|
43
|
+
transport: safeTransport,
|
|
44
|
+
});
|
|
45
|
+
const pimlicoClient = (0, pimlico_1.createPimlicoClient)({
|
|
46
|
+
entryPoint,
|
|
47
|
+
transport: pimlicoTransport,
|
|
48
|
+
});
|
|
49
|
+
// Create a dummy signer for the PKP address
|
|
50
|
+
const dummySigner = addressToAccount(permittedAddress);
|
|
51
|
+
// We re-instantiate the account using the Safe address and the dummy PKP as the signer
|
|
52
|
+
const safeAccount = await (0, accounts_2.toSafeSmartAccount)({
|
|
53
|
+
entryPoint,
|
|
54
|
+
address: safeAddress,
|
|
55
|
+
client: publicClient,
|
|
56
|
+
owners: [dummySigner],
|
|
57
|
+
version: safeVersion,
|
|
58
|
+
});
|
|
59
|
+
const safeClient = (0, permissionless_1.createSmartAccountClient)({
|
|
60
|
+
chain,
|
|
61
|
+
account: safeAccount,
|
|
62
|
+
bundlerTransport: pimlicoTransport,
|
|
63
|
+
client: publicClient,
|
|
64
|
+
paymaster: pimlicoClient,
|
|
65
|
+
});
|
|
66
|
+
const calls = transactions.map((tx) => ({
|
|
67
|
+
data: tx.data,
|
|
68
|
+
to: tx.to,
|
|
69
|
+
value: tx.value,
|
|
70
|
+
}));
|
|
71
|
+
const userOp = await safeClient.prepareUserOperation({
|
|
72
|
+
calls,
|
|
73
|
+
account: safeAccount,
|
|
74
|
+
});
|
|
75
|
+
console.log('[transactionsToSafeUserOp] Prepared unsigned userOp');
|
|
76
|
+
return userOp;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Send a signed Safe UserOp to the bundler.
|
|
80
|
+
* Returns the transaction hash.
|
|
81
|
+
*/
|
|
82
|
+
async function sendPermittedSafeUserOperation({ signedUserOp, chain, pimlicoRpcUrl, }) {
|
|
83
|
+
const pimlicoTransport = (0, viem_1.http)(pimlicoRpcUrl);
|
|
84
|
+
const bundlerClient = (0, account_abstraction_1.createBundlerClient)({
|
|
85
|
+
chain,
|
|
86
|
+
transport: pimlicoTransport,
|
|
87
|
+
});
|
|
88
|
+
console.log('[sendPermittedSafeUserOperation] Broadcasting user op to the network...');
|
|
89
|
+
const userOpHash = await bundlerClient.sendUserOperation(signedUserOp);
|
|
90
|
+
console.log('[sendPermittedSafeUserOperation] UserOp hash:', userOpHash);
|
|
91
|
+
const receipt = await bundlerClient.waitForUserOperationReceipt({
|
|
92
|
+
hash: userOpHash,
|
|
93
|
+
});
|
|
94
|
+
const txHash = receipt.receipt.transactionHash;
|
|
95
|
+
console.log('[sendPermittedSafeUserOperation] Transaction hash:', txHash);
|
|
96
|
+
return txHash;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=safe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe.js","sourceRoot":"","sources":["../../../../src/lib/helpers/safe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transactionKind.d.ts","sourceRoot":"","sources":["../../../../src/lib/helpers/transactionKind.ts"],"names":[],"mappings":"AAAA,oBAAY,eAAe;IACzB,UAAU,eAAe;IACzB,KAAK,UAAU;CAChB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TransactionKind = void 0;
|
|
4
|
+
var TransactionKind;
|
|
5
|
+
(function (TransactionKind) {
|
|
6
|
+
TransactionKind["RELAY_LINK"] = "relay-link";
|
|
7
|
+
TransactionKind["ERC20"] = "erc20";
|
|
8
|
+
})(TransactionKind || (exports.TransactionKind = TransactionKind = {}));
|
|
9
|
+
//# sourceMappingURL=transactionKind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transactionKind.js","sourceRoot":"","sources":["../../../../src/lib/helpers/transactionKind.ts"],"names":[],"mappings":";;;AAAA,IAAY,eAGX;AAHD,WAAY,eAAe;IACzB,4CAAyB,CAAA;IACzB,kCAAe,CAAA;AACjB,CAAC,EAHW,eAAe,+BAAf,eAAe,QAG1B"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Chain, Hex } from 'viem';
|
|
2
|
+
export interface ZerodevTransaction {
|
|
3
|
+
to: `0x${string}`;
|
|
4
|
+
data: `0x${string}`;
|
|
5
|
+
value: string;
|
|
6
|
+
}
|
|
7
|
+
export interface RelayTransactionToUserOpParams {
|
|
8
|
+
permittedAddress: `0x${string}`;
|
|
9
|
+
serializedPermissionAccount: string;
|
|
10
|
+
transaction: {
|
|
11
|
+
to: `0x${string}`;
|
|
12
|
+
data: `0x${string}`;
|
|
13
|
+
value: string;
|
|
14
|
+
chainId: number;
|
|
15
|
+
from: `0x${string}`;
|
|
16
|
+
};
|
|
17
|
+
chain: Chain;
|
|
18
|
+
zerodevRpcUrl: string;
|
|
19
|
+
}
|
|
20
|
+
export interface TransactionsToZerodevUserOpParams {
|
|
21
|
+
permittedAddress: `0x${string}`;
|
|
22
|
+
serializedPermissionAccount: string;
|
|
23
|
+
transactions: ZerodevTransaction[];
|
|
24
|
+
chain: Chain;
|
|
25
|
+
zerodevRpcUrl: string;
|
|
26
|
+
}
|
|
27
|
+
export interface SubmitSignedUserOpParams {
|
|
28
|
+
permittedAddress: `0x${string}`;
|
|
29
|
+
serializedPermissionAccount: string;
|
|
30
|
+
userOpSignature: Hex;
|
|
31
|
+
userOp: Record<string, unknown>;
|
|
32
|
+
chain: Chain;
|
|
33
|
+
zerodevRpcUrl: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Convert multiple transactions to a single batched UserOperation for smart account execution.
|
|
37
|
+
* This is useful for operations that require multiple steps (e.g., ERC20 approve + swap).
|
|
38
|
+
*/
|
|
39
|
+
export declare function transactionsToZerodevUserOp(params: TransactionsToZerodevUserOpParams): Promise<Record<string, unknown>>;
|
|
40
|
+
/**
|
|
41
|
+
* Convert a Relay.link transaction to a UserOperation for smart account execution.
|
|
42
|
+
* This is a convenience wrapper around transactionsToZerodevUserOp for single transactions.
|
|
43
|
+
*/
|
|
44
|
+
export declare function relayTransactionToUserOp(params: RelayTransactionToUserOpParams): Promise<Record<string, unknown>>;
|
|
45
|
+
/**
|
|
46
|
+
* Submit a signed UserOperation to the ZeroDev bundler.
|
|
47
|
+
*
|
|
48
|
+
* This follows the Kernel v3 signature format:
|
|
49
|
+
* - The signature is prefixed with 0xff to indicate "raw signature mode"
|
|
50
|
+
* - This tells the Kernel account to use the signature as-is without additional processing
|
|
51
|
+
*
|
|
52
|
+
* Returns both the UserOp hash and the transaction hash once mined.
|
|
53
|
+
*/
|
|
54
|
+
export declare function submitSignedUserOp(params: SubmitSignedUserOpParams): Promise<{
|
|
55
|
+
userOpHash: Hex;
|
|
56
|
+
transactionHash: Hex;
|
|
57
|
+
}>;
|
|
58
|
+
//# sourceMappingURL=zerodev.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zerodev.d.ts","sourceRoot":"","sources":["../../../../src/lib/helpers/zerodev.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAUvC,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,KAAK,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,8BAA8B;IAC7C,gBAAgB,EAAE,KAAK,MAAM,EAAE,CAAC;IAChC,2BAA2B,EAAE,MAAM,CAAC;IACpC,WAAW,EAAE;QACX,EAAE,EAAE,KAAK,MAAM,EAAE,CAAC;QAClB,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,KAAK,EAAE,KAAK,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iCAAiC;IAChD,gBAAgB,EAAE,KAAK,MAAM,EAAE,CAAC;IAChC,2BAA2B,EAAE,MAAM,CAAC;IACpC,YAAY,EAAE,kBAAkB,EAAE,CAAC;IACnC,KAAK,EAAE,KAAK,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACvC,gBAAgB,EAAE,KAAK,MAAM,EAAE,CAAC;IAChC,2BAA2B,EAAE,MAAM,CAAC;IACpC,eAAe,EAAE,GAAG,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,KAAK,EAAE,KAAK,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;CACvB;AAaD;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,iCAAiC,GACxC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA6ClC;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,8BAA8B,GACrC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAiBlC;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC;IAAE,UAAU,EAAE,GAAG,CAAC;IAAC,eAAe,EAAE,GAAG,CAAA;CAAE,CAAC,CA+DpD"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.transactionsToZerodevUserOp = transactionsToZerodevUserOp;
|
|
4
|
+
exports.relayTransactionToUserOp = relayTransactionToUserOp;
|
|
5
|
+
exports.submitSignedUserOp = submitSignedUserOp;
|
|
6
|
+
const viem_1 = require("viem");
|
|
7
|
+
const permissions_1 = require("@zerodev/permissions");
|
|
8
|
+
const signers_1 = require("@zerodev/permissions/signers");
|
|
9
|
+
const sdk_1 = require("@zerodev/sdk");
|
|
10
|
+
const constants_1 = require("@zerodev/sdk/constants");
|
|
11
|
+
const kernelVersion = constants_1.KERNEL_V3_3;
|
|
12
|
+
const entryPoint = (0, constants_1.getEntryPoint)('0.7');
|
|
13
|
+
/**
|
|
14
|
+
* Creates the modular signer for deserializing permission accounts.
|
|
15
|
+
* This matches how the permission account was created during setup.
|
|
16
|
+
*/
|
|
17
|
+
async function createPermittedSigner(permittedAddress) {
|
|
18
|
+
const permittedEmptyAccount = (0, sdk_1.addressToEmptyAccount)(permittedAddress);
|
|
19
|
+
return await (0, signers_1.toECDSASigner)({
|
|
20
|
+
signer: permittedEmptyAccount,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Convert multiple transactions to a single batched UserOperation for smart account execution.
|
|
25
|
+
* This is useful for operations that require multiple steps (e.g., ERC20 approve + swap).
|
|
26
|
+
*/
|
|
27
|
+
async function transactionsToZerodevUserOp(params) {
|
|
28
|
+
const { permittedAddress, serializedPermissionAccount, transactions, chain, zerodevRpcUrl } = params;
|
|
29
|
+
// Create ZeroDev transport
|
|
30
|
+
const zerodevTransport = (0, viem_1.http)(zerodevRpcUrl);
|
|
31
|
+
// Create public client
|
|
32
|
+
const publicClient = (0, viem_1.createPublicClient)({
|
|
33
|
+
chain,
|
|
34
|
+
transport: zerodevTransport,
|
|
35
|
+
});
|
|
36
|
+
// Create the signer that matches how the permission account was serialized
|
|
37
|
+
const permittedSigner = await createPermittedSigner(permittedAddress);
|
|
38
|
+
// Deserialize the permission account with the signer
|
|
39
|
+
const permissionAccount = await (0, permissions_1.deserializePermissionAccount)(publicClient, entryPoint, kernelVersion, serializedPermissionAccount, permittedSigner);
|
|
40
|
+
// Create kernel client with the permission account
|
|
41
|
+
const kernelClient = (0, sdk_1.createKernelAccountClient)({
|
|
42
|
+
chain,
|
|
43
|
+
account: permissionAccount,
|
|
44
|
+
bundlerTransport: zerodevTransport,
|
|
45
|
+
client: publicClient,
|
|
46
|
+
});
|
|
47
|
+
// Prepare the UserOp with batched calls
|
|
48
|
+
const userOp = await kernelClient.prepareUserOperation({
|
|
49
|
+
callData: await permissionAccount.encodeCalls(transactions.map((tx) => ({
|
|
50
|
+
to: tx.to,
|
|
51
|
+
value: BigInt(tx.value || '0'),
|
|
52
|
+
data: tx.data,
|
|
53
|
+
}))),
|
|
54
|
+
});
|
|
55
|
+
return userOp;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Convert a Relay.link transaction to a UserOperation for smart account execution.
|
|
59
|
+
* This is a convenience wrapper around transactionsToZerodevUserOp for single transactions.
|
|
60
|
+
*/
|
|
61
|
+
async function relayTransactionToUserOp(params) {
|
|
62
|
+
const { permittedAddress, serializedPermissionAccount, transaction, chain, zerodevRpcUrl } = params;
|
|
63
|
+
return transactionsToZerodevUserOp({
|
|
64
|
+
permittedAddress,
|
|
65
|
+
serializedPermissionAccount,
|
|
66
|
+
transactions: [
|
|
67
|
+
{
|
|
68
|
+
to: transaction.to,
|
|
69
|
+
data: transaction.data,
|
|
70
|
+
value: transaction.value,
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
chain,
|
|
74
|
+
zerodevRpcUrl,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Submit a signed UserOperation to the ZeroDev bundler.
|
|
79
|
+
*
|
|
80
|
+
* This follows the Kernel v3 signature format:
|
|
81
|
+
* - The signature is prefixed with 0xff to indicate "raw signature mode"
|
|
82
|
+
* - This tells the Kernel account to use the signature as-is without additional processing
|
|
83
|
+
*
|
|
84
|
+
* Returns both the UserOp hash and the transaction hash once mined.
|
|
85
|
+
*/
|
|
86
|
+
async function submitSignedUserOp(params) {
|
|
87
|
+
const { permittedAddress, serializedPermissionAccount, userOpSignature, userOp, chain, zerodevRpcUrl, } = params;
|
|
88
|
+
// Create ZeroDev transport for bundler
|
|
89
|
+
const zerodevTransport = (0, viem_1.http)(zerodevRpcUrl);
|
|
90
|
+
// Create public client
|
|
91
|
+
const publicClient = (0, viem_1.createPublicClient)({
|
|
92
|
+
chain,
|
|
93
|
+
transport: zerodevTransport,
|
|
94
|
+
});
|
|
95
|
+
// Create the signer that matches how the permission account was serialized
|
|
96
|
+
const permittedSigner = await createPermittedSigner(permittedAddress);
|
|
97
|
+
// Deserialize the permission account with the signer
|
|
98
|
+
const permissionAccount = await (0, permissions_1.deserializePermissionAccount)(publicClient, entryPoint, kernelVersion, serializedPermissionAccount, permittedSigner);
|
|
99
|
+
// Create kernel client with ZeroDev bundler
|
|
100
|
+
// No paymaster - smart account will pay for gas using its own balance
|
|
101
|
+
const kernelClient = (0, sdk_1.createKernelAccountClient)({
|
|
102
|
+
chain,
|
|
103
|
+
account: permissionAccount,
|
|
104
|
+
bundlerTransport: zerodevTransport,
|
|
105
|
+
client: publicClient,
|
|
106
|
+
});
|
|
107
|
+
// Add signature to UserOp with 0xff prefix per Kernel v3 validation
|
|
108
|
+
// The 0xff prefix indicates "raw signature mode" - use signature as-is
|
|
109
|
+
const signedUserOp = {
|
|
110
|
+
...userOp,
|
|
111
|
+
signature: (0, viem_1.concat)(['0xff', userOpSignature]),
|
|
112
|
+
};
|
|
113
|
+
console.log('[submitSignedUserOp] Broadcasting UserOp to ZeroDev bundler...');
|
|
114
|
+
const userOpHash = await kernelClient.sendUserOperation(signedUserOp);
|
|
115
|
+
console.log(`[submitSignedUserOp] UserOp hash: ${userOpHash}`);
|
|
116
|
+
console.log('[submitSignedUserOp] Waiting for UserOp to be included in a block...');
|
|
117
|
+
const receipt = await kernelClient.waitForUserOperationReceipt({
|
|
118
|
+
hash: userOpHash,
|
|
119
|
+
});
|
|
120
|
+
console.log('[submitSignedUserOp] ✅ UserOp executed successfully!');
|
|
121
|
+
console.log(`[submitSignedUserOp] Transaction hash: ${receipt.receipt.transactionHash}`);
|
|
122
|
+
return {
|
|
123
|
+
userOpHash,
|
|
124
|
+
transactionHash: receipt.receipt.transactionHash,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=zerodev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zerodev.js","sourceRoot":"","sources":["../../../../src/lib/helpers/zerodev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lit-action.d.ts","sourceRoot":"","sources":["../../../src/lib/lit-action.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vincent_ability_sdk_1 = require("@lit-protocol/vincent-ability-sdk");
|
|
4
|
+
const vincent_ability_1 = require("src/lib/vincent-ability");
|
|
5
|
+
(async () => {
|
|
6
|
+
const func = (0, vincent_ability_sdk_1.vincentAbilityHandler)({
|
|
7
|
+
vincentAbility: vincent_ability_1.vincentAbility,
|
|
8
|
+
context: {
|
|
9
|
+
delegatorPkpEthAddress: context.delegatorPkpEthAddress,
|
|
10
|
+
},
|
|
11
|
+
abilityParams,
|
|
12
|
+
});
|
|
13
|
+
await func();
|
|
14
|
+
})();
|
|
15
|
+
//# sourceMappingURL=lit-action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lit-action.js","sourceRoot":"","sources":["../../../src/lib/lit-action.ts"],"names":[],"mappings":";;AAEA,2EAA0E;AAE1E,6DAAyD;AASzD,CAAC,KAAK,IAAI,EAAE;IACV,MAAM,IAAI,GAAG,IAAA,2CAAqB,EAAC;QACjC,cAAc,EAAE,gCAAc;QAC9B,OAAO,EAAE;YACP,sBAAsB,EAAE,OAAO,CAAC,sBAAsB;SACvD;QACD,aAAa;KACd,CAAC,CAAC;IACH,MAAM,IAAI,EAAE,CAAC;AACf,CAAC,CAAC,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateSimulation.d.ts","sourceRoot":"","sources":["../../../src/lib/validateSimulation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EAEzB,MAAM,+CAA+C,CAAC;AAevD,eAAO,MAAM,kBAAkB,GAAU,QAAQ,wBAAwB,kBAkIxE,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateSimulation = void 0;
|
|
4
|
+
const viem_1 = require("viem");
|
|
5
|
+
const relay_link_1 = require("./helpers/relay-link");
|
|
6
|
+
// Fixed Relay Solver address for EVM chains
|
|
7
|
+
// See: https://docs.relay.link/references/solver-addresses
|
|
8
|
+
const RELAY_SOLVER_ADDRESS = '0xf70da97812cb96acdf810712aa562db8dfa3dbef';
|
|
9
|
+
// Fee range in basis points (1 bps = 0.01%)
|
|
10
|
+
const MIN_FEE_BPS = 0n; // 0%
|
|
11
|
+
const MAX_FEE_BPS = 100n; // 1%
|
|
12
|
+
const validateSimulation = async (params) => {
|
|
13
|
+
const { chainId, sender: _sender, simulation } = params;
|
|
14
|
+
if (simulation.error) {
|
|
15
|
+
const { message, revertReason } = simulation.error;
|
|
16
|
+
throw new Error(`Simulation failed - Reason: ${revertReason} - Message: ${message}`);
|
|
17
|
+
}
|
|
18
|
+
// Fetch Relay contract addresses from the API
|
|
19
|
+
const relayAddresses = await (0, relay_link_1.fetchRelayLinkAddresses)(chainId);
|
|
20
|
+
const sender = (0, viem_1.getAddress)(_sender, chainId);
|
|
21
|
+
// Build set of allowed addresses: sender, zero address, and all Relay.link contracts
|
|
22
|
+
const relayAddressesNormalized = relayAddresses.map((a) => (0, viem_1.getAddress)(a, chainId));
|
|
23
|
+
const allowed = new Set([viem_1.zeroAddress, sender, ...relayAddressesNormalized]);
|
|
24
|
+
// Normalize the solver address for comparison
|
|
25
|
+
const solverAddress = (0, viem_1.getAddress)(RELAY_SOLVER_ADDRESS, chainId);
|
|
26
|
+
// Track input amounts per token (ERC20 transfers FROM sender)
|
|
27
|
+
const inputByToken = new Map();
|
|
28
|
+
// Track fee amounts per token (ERC20 transfers TO the Relay Solver)
|
|
29
|
+
const feesByToken = new Map();
|
|
30
|
+
simulation.changes.forEach((c, idx) => {
|
|
31
|
+
const assetType = c.assetType;
|
|
32
|
+
const changeType = c.changeType;
|
|
33
|
+
const from = (0, viem_1.getAddress)(c.from, chainId);
|
|
34
|
+
const to = (0, viem_1.getAddress)(c.to, chainId);
|
|
35
|
+
// Helper for throwing with context
|
|
36
|
+
const fail = (reason) => {
|
|
37
|
+
throw new Error(`Invalid simulation change at index ${idx}: ${reason} [assetType=${assetType}, changeType=${changeType}, from=${from}, to=${to}]`);
|
|
38
|
+
};
|
|
39
|
+
if (assetType === 'NATIVE') {
|
|
40
|
+
if (changeType !== 'TRANSFER') {
|
|
41
|
+
fail('Only TRANSFER is allowed for NATIVE');
|
|
42
|
+
}
|
|
43
|
+
// Track native input (from sender) - use zeroAddress as the "token" for native ETH
|
|
44
|
+
if (from === sender && c.rawAmount) {
|
|
45
|
+
inputByToken.set(viem_1.zeroAddress, (inputByToken.get(viem_1.zeroAddress) || 0n) + BigInt(c.rawAmount));
|
|
46
|
+
}
|
|
47
|
+
// Track native fee (to solver)
|
|
48
|
+
if (to === solverAddress && c.rawAmount) {
|
|
49
|
+
feesByToken.set(viem_1.zeroAddress, (feesByToken.get(viem_1.zeroAddress) || 0n) + BigInt(c.rawAmount));
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (assetType === 'ERC20') {
|
|
54
|
+
if (changeType === 'APPROVE') {
|
|
55
|
+
// We only validate approvals FROM the sender to ensure user tokens aren't
|
|
56
|
+
// approved to malicious contracts. Intermediate approvals (from DEX aggregators,
|
|
57
|
+
// routers, or other contracts in the swap route) are orchestrated by Relay.link
|
|
58
|
+
// and don't affect the user's tokens directly.
|
|
59
|
+
if (from === sender) {
|
|
60
|
+
// Sender's approvals must go to known Relay.link contracts
|
|
61
|
+
const isToRelay = relayAddressesNormalized.some((addr) => addr === to);
|
|
62
|
+
if (!isToRelay) {
|
|
63
|
+
fail('ERC20 APPROVE from sender must go to a Relay.link contract');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Approvals from other addresses (intermediate contracts) are allowed
|
|
67
|
+
// as they're part of Relay.link's swap orchestration
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (changeType === 'TRANSFER') {
|
|
71
|
+
// For transfers FROM sender, ensure they go to allowed addresses (Relay contracts)
|
|
72
|
+
// For transfers TO sender, they're always allowed (receiving funds)
|
|
73
|
+
// Intermediate transfers (between aggregator contracts) are allowed since Relay orchestrates them
|
|
74
|
+
if (from === sender && !allowed.has(to)) {
|
|
75
|
+
fail('ERC20 TRANSFER from sender must go to a Relay.link contract');
|
|
76
|
+
}
|
|
77
|
+
// Track input amounts (transfers FROM sender)
|
|
78
|
+
if (from === sender && c.contractAddress && c.rawAmount) {
|
|
79
|
+
const token = (0, viem_1.getAddress)(c.contractAddress, chainId);
|
|
80
|
+
const amount = BigInt(c.rawAmount);
|
|
81
|
+
inputByToken.set(token, (inputByToken.get(token) || 0n) + amount);
|
|
82
|
+
}
|
|
83
|
+
// Track fee amounts (transfers TO the Relay Solver)
|
|
84
|
+
if (to === solverAddress && c.contractAddress && c.rawAmount) {
|
|
85
|
+
const token = (0, viem_1.getAddress)(c.contractAddress, chainId);
|
|
86
|
+
const amount = BigInt(c.rawAmount);
|
|
87
|
+
feesByToken.set(token, (feesByToken.get(token) || 0n) + amount);
|
|
88
|
+
}
|
|
89
|
+
// Transfers to sender are always allowed (receiving swap output)
|
|
90
|
+
// Intermediate transfers (neither from nor to sender) are allowed as Relay uses aggregators
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// Unknown change type for ERC20
|
|
94
|
+
fail('Unsupported ERC20 change type');
|
|
95
|
+
}
|
|
96
|
+
// Any other asset types are not permitted
|
|
97
|
+
fail('Unsupported asset type');
|
|
98
|
+
});
|
|
99
|
+
// Validate fee percentages for tokens where we detected both input and fees
|
|
100
|
+
for (const [token, feeAmount] of feesByToken) {
|
|
101
|
+
const inputAmount = inputByToken.get(token);
|
|
102
|
+
// Only validate if we have input for this token (otherwise we can't calculate a percentage)
|
|
103
|
+
if (inputAmount && inputAmount > 0n) {
|
|
104
|
+
// Calculate fee in basis points: (fee / input) * 10000
|
|
105
|
+
const feeBps = (feeAmount * 10000n) / inputAmount;
|
|
106
|
+
if (feeBps < MIN_FEE_BPS) {
|
|
107
|
+
throw new Error(`Fee too low: ${feeBps} bps for token ${token}. Minimum allowed: ${MIN_FEE_BPS} bps`);
|
|
108
|
+
}
|
|
109
|
+
if (feeBps > MAX_FEE_BPS) {
|
|
110
|
+
throw new Error(`Fee too high: ${feeBps} bps for token ${token}. Maximum allowed: ${MAX_FEE_BPS} bps`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
exports.validateSimulation = validateSimulation;
|
|
116
|
+
//# sourceMappingURL=validateSimulation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateSimulation.js","sourceRoot":"","sources":["../../../src/lib/validateSimulation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateTransaction.d.ts","sourceRoot":"","sources":["../../../src/lib/validateTransaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,yBAAyB,EAC1B,MAAM,+CAA+C,CAAC;AAQvD,eAAO,MAAM,mBAAmB,GAAU,QAAQ,yBAAyB,kBAuD1E,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateTransaction = void 0;
|
|
4
|
+
const viem_1 = require("viem");
|
|
5
|
+
const relay_link_1 = require("./helpers/relay-link");
|
|
6
|
+
const transactionKind_1 = require("./helpers/transactionKind");
|
|
7
|
+
const validateTransaction = async (params) => {
|
|
8
|
+
const { chainId, decodedTransaction } = params;
|
|
9
|
+
if (decodedTransaction.kind === 'error') {
|
|
10
|
+
const decodedTransactionError = decodedTransaction;
|
|
11
|
+
throw new Error(`Transaction failed to decode: ${decodedTransactionError.message}`);
|
|
12
|
+
}
|
|
13
|
+
const decodedTransactionSuccess = decodedTransaction;
|
|
14
|
+
// Fetch Relay.link addresses for this chain from the API
|
|
15
|
+
const relayAddresses = await (0, relay_link_1.fetchRelayLinkAddresses)(chainId);
|
|
16
|
+
// Validate ERC20 transactions (approvals for Relay.link contracts)
|
|
17
|
+
if (decodedTransaction.kind === transactionKind_1.TransactionKind.ERC20) {
|
|
18
|
+
if (['approve', 'increaseAllowance'].includes(decodedTransactionSuccess.fn)) {
|
|
19
|
+
const [spender, amount] = decodedTransactionSuccess.args;
|
|
20
|
+
// Only allow approvals to Relay.link contracts
|
|
21
|
+
const isRelaySpender = relayAddresses.some((addr) => (0, viem_1.isAddressEqual)(spender, addr));
|
|
22
|
+
if (!isRelaySpender) {
|
|
23
|
+
throw new Error(`ERC20 approval to non-Relay.link spender ${spender}. Allowed: ${relayAddresses.join(', ')}`);
|
|
24
|
+
}
|
|
25
|
+
// Block infinite approvals for safety
|
|
26
|
+
if (amount === 2n ** 256n - 1n) {
|
|
27
|
+
throw new Error('Infinite approval not allowed');
|
|
28
|
+
}
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
throw new Error(`ERC20 function ${decodedTransactionSuccess.fn} not allowed`);
|
|
32
|
+
}
|
|
33
|
+
// Validate Relay.link transactions
|
|
34
|
+
if (decodedTransaction.kind === transactionKind_1.TransactionKind.RELAY_LINK) {
|
|
35
|
+
const isValidTarget = relayAddresses.some((addr) => (0, viem_1.isAddressEqual)(decodedTransactionSuccess.to, addr));
|
|
36
|
+
if (!isValidTarget) {
|
|
37
|
+
throw new Error(`Transaction target ${decodedTransactionSuccess.to} is not a known Relay.link contract. Allowed: ${relayAddresses.join(', ')}`);
|
|
38
|
+
}
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
throw new Error(`Unknown transaction kind: ${decodedTransaction.kind}. Only ERC20 approvals and Relay.link transactions are allowed.`);
|
|
42
|
+
};
|
|
43
|
+
exports.validateTransaction = validateTransaction;
|
|
44
|
+
//# sourceMappingURL=validateTransaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateTransaction.js","sourceRoot":"","sources":["../../../src/lib/validateTransaction.ts"],"names":[],"mappings":";;;AAOA,+BAAsC;AAEtC,qDAA+D;AAC/D,+DAA4D;AAErD,MAAM,mBAAmB,GAAG,KAAK,EAAE,MAAiC,EAAE,EAAE;IAC7E,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,GAAG,MAAM,CAAC;IAE/C,IAAI,kBAAkB,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACxC,MAAM,uBAAuB,GAAG,kBAA6C,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,iCAAiC,uBAAuB,CAAC,OAAO,EAAE,CAAC,CAAC;IACtF,CAAC;IAED,MAAM,yBAAyB,GAAG,kBAA+C,CAAC;IAElF,yDAAyD;IACzD,MAAM,cAAc,GAAG,MAAM,IAAA,oCAAuB,EAAC,OAAO,CAAC,CAAC;IAE9D,mEAAmE;IACnE,IAAI,kBAAkB,CAAC,IAAI,KAAK,iCAAe,CAAC,KAAK,EAAE,CAAC;QACtD,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC;YAC5E,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,yBAAyB,CAAC,IAAyB,CAAC;YAE9E,+CAA+C;YAC/C,MAAM,cAAc,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,qBAAc,EAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;YACpF,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CACb,4CAA4C,OAAO,cAAc,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7F,CAAC;YACJ,CAAC;YAED,sCAAsC;YACtC,IAAI,MAAM,KAAK,EAAE,IAAI,IAAI,GAAG,EAAE,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACnD,CAAC;YAED,OAAO;QACT,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,kBAAkB,yBAAyB,CAAC,EAAE,cAAc,CAAC,CAAC;IAChF,CAAC;IAED,mCAAmC;IACnC,IAAI,kBAAkB,CAAC,IAAI,KAAK,iCAAe,CAAC,UAAU,EAAE,CAAC;QAC3D,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACjD,IAAA,qBAAc,EAAC,yBAAyB,CAAC,EAAa,EAAE,IAAI,CAAC,CAC9D,CAAC;QAEF,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,sBAAsB,yBAAyB,CAAC,EAAE,iDAAiD,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/H,CAAC;QACJ,CAAC;QAED,OAAO;IACT,CAAC;IAED,MAAM,IAAI,KAAK,CACb,6BAA6B,kBAAkB,CAAC,IAAI,iEAAiE,CACtH,CAAC;AACJ,CAAC,CAAC;AAvDW,QAAA,mBAAmB,uBAuD9B"}
|