@lit-protocol/vincent-ability-uniswap-swap 2.0.1 → 4.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.
Files changed (83) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +94 -83
  3. package/dist/CHANGELOG.md +15 -0
  4. package/dist/README.md +94 -83
  5. package/dist/package.json +6 -4
  6. package/dist/src/generated/lit-action-prepare.js +9 -0
  7. package/dist/src/generated/lit-action.js +2 -2
  8. package/dist/src/generated/vincent-ability-metadata.json +1 -1
  9. package/dist/src/generated/vincent-bundled-ability.d.ts +139 -946
  10. package/dist/src/generated/vincent-bundled-ability.d.ts.map +1 -1
  11. package/dist/src/generated/vincent-prepare-metadata.json +6 -0
  12. package/dist/src/index.d.ts +3 -0
  13. package/dist/src/index.d.ts.map +1 -1
  14. package/dist/src/index.js +5 -1
  15. package/dist/src/index.js.map +1 -1
  16. package/dist/src/lib/ability-checks/check-token-in-balance.d.ts +1 -1
  17. package/dist/src/lib/ability-checks/check-token-in-balance.d.ts.map +1 -1
  18. package/dist/src/lib/ability-checks/check-token-in-balance.js.map +1 -1
  19. package/dist/src/lib/ability-checks/index.d.ts +0 -1
  20. package/dist/src/lib/ability-checks/index.d.ts.map +1 -1
  21. package/dist/src/lib/ability-checks/index.js +0 -1
  22. package/dist/src/lib/ability-checks/index.js.map +1 -1
  23. package/dist/src/lib/ability-helpers/get-gas-params.d.ts +1 -1
  24. package/dist/src/lib/ability-helpers/get-gas-params.d.ts.map +1 -1
  25. package/dist/src/lib/ability-helpers/get-gas-params.js +5 -3
  26. package/dist/src/lib/ability-helpers/get-gas-params.js.map +1 -1
  27. package/dist/src/lib/ability-helpers/get-uniswap-quote.d.ts +6 -11
  28. package/dist/src/lib/ability-helpers/get-uniswap-quote.d.ts.map +1 -1
  29. package/dist/src/lib/ability-helpers/get-uniswap-quote.js +59 -104
  30. package/dist/src/lib/ability-helpers/get-uniswap-quote.js.map +1 -1
  31. package/dist/src/lib/ability-helpers/index.d.ts +0 -4
  32. package/dist/src/lib/ability-helpers/index.d.ts.map +1 -1
  33. package/dist/src/lib/ability-helpers/index.js +0 -4
  34. package/dist/src/lib/ability-helpers/index.js.map +1 -1
  35. package/dist/src/lib/ability-helpers/send-uniswap-tx.d.ts +8 -8
  36. package/dist/src/lib/ability-helpers/send-uniswap-tx.d.ts.map +1 -1
  37. package/dist/src/lib/ability-helpers/send-uniswap-tx.js +25 -53
  38. package/dist/src/lib/ability-helpers/send-uniswap-tx.js.map +1 -1
  39. package/dist/src/lib/prepare/get-signed-uniswap-quote.d.ts +9 -0
  40. package/dist/src/lib/prepare/get-signed-uniswap-quote.d.ts.map +1 -0
  41. package/dist/src/lib/prepare/get-signed-uniswap-quote.js +57 -0
  42. package/dist/src/lib/prepare/get-signed-uniswap-quote.js.map +1 -0
  43. package/dist/src/lib/prepare/lit-action.d.ts +2 -0
  44. package/dist/src/lib/prepare/lit-action.d.ts.map +1 -0
  45. package/dist/src/lib/prepare/lit-action.js +88 -0
  46. package/dist/src/lib/prepare/lit-action.js.map +1 -0
  47. package/dist/src/lib/prepare/types.d.ts +49 -0
  48. package/dist/src/lib/prepare/types.d.ts.map +1 -0
  49. package/dist/src/lib/prepare/types.js +3 -0
  50. package/dist/src/lib/prepare/types.js.map +1 -0
  51. package/dist/src/lib/prepare/validate-signed-uniswap-quote.d.ts +7 -0
  52. package/dist/src/lib/prepare/validate-signed-uniswap-quote.d.ts.map +1 -0
  53. package/dist/src/lib/prepare/validate-signed-uniswap-quote.js +25 -0
  54. package/dist/src/lib/prepare/validate-signed-uniswap-quote.js.map +1 -0
  55. package/dist/src/lib/schemas.d.ts +140 -62
  56. package/dist/src/lib/schemas.d.ts.map +1 -1
  57. package/dist/src/lib/schemas.js +27 -41
  58. package/dist/src/lib/schemas.js.map +1 -1
  59. package/dist/src/lib/vincent-ability.d.ts +139 -946
  60. package/dist/src/lib/vincent-ability.d.ts.map +1 -1
  61. package/dist/src/lib/vincent-ability.js +54 -122
  62. package/dist/src/lib/vincent-ability.js.map +1 -1
  63. package/package.json +8 -6
  64. package/dist/src/lib/ability-checks/check-uniswap-pool-exists.d.ts +0 -10
  65. package/dist/src/lib/ability-checks/check-uniswap-pool-exists.d.ts.map +0 -1
  66. package/dist/src/lib/ability-checks/check-uniswap-pool-exists.js +0 -24
  67. package/dist/src/lib/ability-checks/check-uniswap-pool-exists.js.map +0 -1
  68. package/dist/src/lib/ability-helpers/calculate-usd-value.d.ts +0 -7
  69. package/dist/src/lib/ability-helpers/calculate-usd-value.d.ts.map +0 -1
  70. package/dist/src/lib/ability-helpers/calculate-usd-value.js +0 -22
  71. package/dist/src/lib/ability-helpers/calculate-usd-value.js.map +0 -1
  72. package/dist/src/lib/ability-helpers/estimate-gas-for-swap.d.ts +0 -7
  73. package/dist/src/lib/ability-helpers/estimate-gas-for-swap.d.ts.map +0 -1
  74. package/dist/src/lib/ability-helpers/estimate-gas-for-swap.js +0 -24
  75. package/dist/src/lib/ability-helpers/estimate-gas-for-swap.js.map +0 -1
  76. package/dist/src/lib/ability-helpers/get-eth-usd-price.d.ts +0 -6
  77. package/dist/src/lib/ability-helpers/get-eth-usd-price.d.ts.map +0 -1
  78. package/dist/src/lib/ability-helpers/get-eth-usd-price.js +0 -22
  79. package/dist/src/lib/ability-helpers/get-eth-usd-price.js.map +0 -1
  80. package/dist/src/lib/ability-helpers/get-token-amount-in-usd.d.ts +0 -10
  81. package/dist/src/lib/ability-helpers/get-token-amount-in-usd.d.ts.map +0 -1
  82. package/dist/src/lib/ability-helpers/get-token-amount-in-usd.js +0 -68
  83. package/dist/src/lib/ability-helpers/get-token-amount-in-usd.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # 3.0.0 (2025-09-11)
2
+
3
+ ### ⚠️ Breaking Changes
4
+
5
+ - Refactor the Uniswap Swap Ability to utilize a prepare step which uses a Lit Action to generate and sign a Uniswap route generated by the V3 Alpha Router. The Swap Ability now intakes the signed route, validates it was signed by the expected PKP (which can only be used to sign the generated Uniswap routes within the prepare Lit Action), then uses the provided route to create and sign the Uniswap Swap transaction with the Agent Wallet PKP. The Uniswap Swap Ability was also updated to no longer support the Spending Limit Policy, and currently doesn't support any Policies. ([8bbb1c07](https://github.com/LIT-Protocol/Vincent/commit/8bbb1c07))
6
+
7
+ ### 🧱 Updated Dependencies
8
+
9
+ - Updated ability-sdk to 2.1.0
10
+ - Updated app-sdk to 2.1.0
11
+
12
+ ### ❤️ Thank You
13
+
14
+ - Wyatt Barnes @spacesailor24
15
+
1
16
  ## 2.0.1 (2025-09-03)
2
17
 
3
18
  ### 🧱 Updated Dependencies
package/README.md CHANGED
@@ -1,18 +1,13 @@
1
1
  # Vincent Ability Uniswap Swap
2
2
 
3
- An ability to trigger swaps on Uniswap from a Vincent app on behalf of the delegator.
4
-
5
- ## Overview
6
-
7
- The Vincent Ability Uniswap Swap is part of the Vincent Abilities ecosystem and is built using the Vincent Ability SDK. It allows Vincent apps to execute token swaps on Uniswap V3 on behalf of users, enabling seamless integration with decentralized exchange functionality.
3
+ This Uniswap Swap Ability is part of the Vincent Abilities ecosystem and is built using the Vincent Ability SDK. It allows Vincent Apps to execute token swaps on Uniswap V3 on behalf of Vincent Users, enabling integration with decentralized exchanges.
8
4
 
9
5
  ## Features
10
6
 
11
7
  - Execute token swaps on Uniswap V3
12
8
  - Support for exact input and exact output swaps
13
- - Support for multiple token pairs
14
- - Integration with spending limit policies for enhanced security
15
- - Support for multiple chains and Uniswap deployments
9
+ - Support for multi-hop swaps through multiple pools
10
+ - Support for multiple chains that Uniswap V3 is deployed to
16
11
 
17
12
  ## Installation
18
13
 
@@ -22,106 +17,122 @@ npm install @lit-protocol/vincent-ability-uniswap-swap
22
17
 
23
18
  ## Usage
24
19
 
25
- This ability can be used in Vincent apps to execute Uniswap swaps:
20
+ To use the Uniswap Swap Ability, you need to generate a signed swap quote first, then provide it to both the `precheck` and `execute` functions.
26
21
 
27
- ```typescript
28
- import { getVincentAbilityClient } from '@lit-protocol/vincent-app-sdk/abilityClient';
29
- import { bundledVincentAbility } from '@lit-protocol/vincent-ability-uniswap-swap';
22
+ ### 1. Generate a Signed Swap Quote
30
23
 
31
- // One of delegatee signers from your app's Vincent Dashboard
32
- const delegateeSigner = new ethers.Wallet('YOUR_DELEGATEE_PRIVATE_KEY');
24
+ Before executing a swap, you must generate a signed quote using the `getSignedUniswapQuote` function:
33
25
 
34
- // Initialize the Vincent Ability Client
35
- const abilityClient = getVincentAbilityClient({
36
- ethersSigner: delegateeSigner,
37
- bundledVincentAbility,
26
+ ```typescript
27
+ import { LitNodeClient } from '@lit-protocol/lit-node-client';
28
+ import { getSignedUniswapQuote } from '@lit-protocol/vincent-ability-uniswap-swap';
29
+ import { ethers } from 'ethers';
30
+
31
+ // Initialize Lit Node Client
32
+ const litNodeClient = new LitNodeClient({
33
+ litNetwork: 'datil',
34
+ debug: true,
38
35
  });
39
- const delegatorPkpEthAddress = '0x09182301238'; // The delegator PKP Eth Address
40
-
41
- const abilityParams = {
42
- chainId: '8453', // The chain where the tx will be executed
43
- tokenIn: '0x1234...', // The input token address
44
- amountIn: '1000000000000000000', // The input amount (in wei)
45
- tokenOut: '0xabcd...', // The output token address
46
- rpcUrl: 'https://mainnet.base.org', // The RPC to send the transaction through
47
- };
48
-
49
- // Run precheck to see if ability should be executed
50
- const precheckResult = await client.precheck(abilityParams, {
51
- delegatorPkpEthAddress,
36
+ await litNodeClient.connect();
37
+
38
+ // Your delegatee signer (one of the delegatee signers for the Vincent App)
39
+ const delegateeSigner = new ethers.Wallet('YOUR_DELEGATEE_PRIVATE_KEY', provider);
40
+
41
+ // Generate the signed quote
42
+ const signedUniswapQuote = await getSignedUniswapQuote({
43
+ quoteParams: {
44
+ rpcUrl: 'https://mainnet.base.org',
45
+ tokenInAddress: '0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed', // DEGEN
46
+ tokenInAmount: '80', // Amount in token's smallest unit
47
+ tokenOutAddress: '0x4200000000000000000000000000000000000006', // WETH
48
+ recipient: delegatorPkpEthAddress, // The PKP that will execute the swap
49
+ },
50
+ ethersSigner: delegateeSigner,
51
+ litNodeClient,
52
52
  });
53
+ ```
53
54
 
54
- if (precheckResult.success === true) {
55
- // Execute the Vincent Ability
56
- const executeResult = await client.execute(abilityParams, {
57
- delegatorPkpEthAddress,
58
- });
55
+ The return value of `getSignedUniswapQuote` is an object containing:
59
56
 
60
- // ...ability has executed, you can check `executeResult` for details
61
- }
62
- ```
57
+ - `quote`: The Uniswap Quote/Route generated by the V3 SDK using the Alpha Router
58
+ - `signature`: A signature of `quote` signed by a Lit PKP that is configured to only ever be able to sign these generated Uniswap Quotes within the specific Lit Action configured by this Ability
59
+ - `dataSigned`: The data signed by the PKP, an ETH Personal Message containing the hash of the stringified `quote`
60
+ - `signerPublicKey`: The public key of the PKP that signed the `quote`
61
+ - `signerEthAddress`: The Ethereum address of the PKP that signed the `quote`
63
62
 
64
- ## Integration with Policies
63
+ Because the Uniswap SDK makes a lot of RPC calls when generating a quote/route, it exceeded the usage limits of Lit Actions when running within the same Lit Action as the Vincent logic for checking and executing Policies, and verifying on-chain delegation.
65
64
 
66
- This ability is integrated with the Vincent Policy Spending Limit to enforce spending constraints:
65
+ So, the purpose of `getSignedUniswapQuote` is to generate a signed quote/route outside of the Vincent Ability Lit Action, and then provide it to the `precheck` and `execute` functions in a tamper-proof manner. The Vincent Delegatee is unable to modify the quote/route after it has been signed by the PKP, because the Ability verifies the provided route data was signed by the hardcoded PKP address.
66
+
67
+ ### 2. Run Precheck
68
+
69
+ Provide the signed `quote` to `precheck` to check if the swap can be executed:
67
70
 
68
71
  ```typescript
69
- import {
70
- createVincentAbilityPolicy,
71
- createVincentAbility,
72
- createPolicyMapFromAbilityPolicies,
73
- } from '@lit-protocol/vincent-ability-sdk';
74
- import { bundledVincentPolicy } from '@lit-protocol/vincent-policy-spending-limit';
75
- import { abilityParamsSchema } from '@lit-protocol/vincent-ability-uniswap-swap';
76
-
77
- const spendingLimitPolicy = createVincentAbilityPolicy({
78
- abilityParamsSchema,
79
- bundledVincentPolicy,
80
- abilityParameterMappings: {
81
- pkpEthAddress: 'pkpEthAddress',
82
- ethRpcUrl: 'ethRpcUrl',
83
- tokenInAddress: 'tokenAddress',
84
- tokenInDecimals: 'tokenDecimals',
85
- tokenInAmount: 'buyAmount',
86
- },
87
- });
72
+ import { getVincentAbilityClient } from '@lit-protocol/vincent-app-sdk/abilityClient';
73
+ import { bundledVincentAbility } from '@lit-protocol/vincent-ability-uniswap-swap';
88
74
 
89
- export const uniswapSwapWithSpendingLimit = createVincentAbility({
90
- abilityParamsSchema,
91
- policyMap: createPolicyMapFromAbilityPolicies([spendingLimitPolicy]),
92
- // ... rest of ability implementation
75
+ // Initialize the ability client
76
+ const abilityClient = getVincentAbilityClient({
77
+ bundledVincentAbility,
78
+ ethersSigner: delegateeSigner,
93
79
  });
94
- ```
95
80
 
96
- ## Prerequisites
81
+ // Run precheck with the signed quote
82
+ const precheckResult = await abilityClient.precheck(
83
+ {
84
+ rpcUrlForUniswap: 'https://mainnet.base.org',
85
+ signedUniswapQuote: {
86
+ quote: signedUniswapQuote.quote,
87
+ signature: signedUniswapQuote.signature,
88
+ },
89
+ },
90
+ {
91
+ delegatorPkpEthAddress: '0x...', // The delegator PKP ETH address
92
+ },
93
+ );
97
94
 
98
- Before executing a swap, ensure that:
95
+ if (precheckResult.success) {
96
+ console.log('Swap can be executed');
97
+ }
98
+ ```
99
99
 
100
- 1. The user has approved the input token for the Uniswap router
101
- 2. The user has sufficient balance of the input token
102
- 3. The user has delegated permission to the Vincent app to execute swaps
100
+ ### 3. Execute the Swap
103
101
 
104
- You can use the Vincent Ability ERC20 Approval to handle token approvals:
102
+ If `precheck` succeeds, execute the swap using the same signed `quote`:
105
103
 
106
104
  ```typescript
107
- import { getVincentAbilityClient } from '@lit-protocol/vincent-app-sdk/abilityClient';
108
- import { ERC20_APPROVAL_TOOL_IPFS_ID } from '@lit-protocol/vincent-ability-erc20-approval';
105
+ const executeResult = await abilityClient.execute(
106
+ {
107
+ rpcUrlForUniswap: 'https://mainnet.base.org',
108
+ signedUniswapQuote: {
109
+ quote: signedUniswapQuote.quote,
110
+ signature: signedUniswapQuote.signature,
111
+ },
112
+ },
113
+ {
114
+ delegatorPkpEthAddress: '0x...', // The delegator PKP ETH address
115
+ },
116
+ );
109
117
 
110
- // ... approve tokens before swap
118
+ if (executeResult.success) {
119
+ console.log('Swap executed successfully!');
120
+ console.log('Transaction hash:', executeResult.result.swapTxHash);
121
+ }
111
122
  ```
112
123
 
113
- ## Building
114
-
115
- Run `nx build ability-uniswap-swap` to build the library.
124
+ A complete example of generating the signed `quote`, running `precheck`, and executing the swap is available in the `abilities-e2e`'s end-to-end [swap.spec.ts](../abilities-e2e/test-e2e/swap.spec.ts) test.
116
125
 
117
- ## Running unit tests
126
+ ## Development
118
127
 
119
- Run `nx test ability-uniswap-swap` to execute the unit tests via [Jest](https://jestjs.io).
128
+ Because of the need for the `getSignedUniswapQuote` function and it's corresponding Lit Action, included in this package is a script ([create-pkp-for-prepare.js](./scripts/create-pkp-for-prepare.js)) that is used to mint the PKP that is configured to only ever be able to sign these generated Uniswap Quotes within the specific Lit Action configured by this Ability.
120
129
 
121
- ## Contributing
130
+ Anytime changes are made to the [Prepare Lit Action](./src/lib/prepare/lit-action.ts), you **MUST** run the PKP minting script to update the PKP info recorded in [vincent-prepare-metadata.json](./src/generated/vincent-prepare-metadata.json) file. You can execute the script using the Nx target:
122
131
 
123
- Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines on how to contribute to this project.
132
+ ```
133
+ pnpm nx run ability-uniswap-swap:action:create-pkp
134
+ ```
124
135
 
125
- ## License
136
+ This will run the `action:deploy` target, which will build the Prepare Lit Action and deploy it to IPFS, recording the IPFS CID in `vincent-prepare-metadata.json` file. Then the `create-pkp-for-prepare.js` script will be executed minting a new PKP that has the IPFS CID of the Prepare Lit Action as the only permitted Auth Method.
126
137
 
127
- This project is licensed under the MIT License - see the LICENSE file for details.
138
+ After making any changes to the Prepare Lit Action, generating a new signer PKP, run the `build` target to update the Swap Ability Lit Action with the new PKP ETH address used for verifying the `quote` signatures.
package/dist/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # 3.0.0 (2025-09-11)
2
+
3
+ ### ⚠️ Breaking Changes
4
+
5
+ - Refactor the Uniswap Swap Ability to utilize a prepare step which uses a Lit Action to generate and sign a Uniswap route generated by the V3 Alpha Router. The Swap Ability now intakes the signed route, validates it was signed by the expected PKP (which can only be used to sign the generated Uniswap routes within the prepare Lit Action), then uses the provided route to create and sign the Uniswap Swap transaction with the Agent Wallet PKP. The Uniswap Swap Ability was also updated to no longer support the Spending Limit Policy, and currently doesn't support any Policies. ([8bbb1c07](https://github.com/LIT-Protocol/Vincent/commit/8bbb1c07))
6
+
7
+ ### 🧱 Updated Dependencies
8
+
9
+ - Updated ability-sdk to 2.1.0
10
+ - Updated app-sdk to 2.1.0
11
+
12
+ ### ❤️ Thank You
13
+
14
+ - Wyatt Barnes @spacesailor24
15
+
1
16
  ## 2.0.1 (2025-09-03)
2
17
 
3
18
  ### 🧱 Updated Dependencies
package/dist/README.md CHANGED
@@ -1,18 +1,13 @@
1
1
  # Vincent Ability Uniswap Swap
2
2
 
3
- An ability to trigger swaps on Uniswap from a Vincent app on behalf of the delegator.
4
-
5
- ## Overview
6
-
7
- The Vincent Ability Uniswap Swap is part of the Vincent Abilities ecosystem and is built using the Vincent Ability SDK. It allows Vincent apps to execute token swaps on Uniswap V3 on behalf of users, enabling seamless integration with decentralized exchange functionality.
3
+ This Uniswap Swap Ability is part of the Vincent Abilities ecosystem and is built using the Vincent Ability SDK. It allows Vincent Apps to execute token swaps on Uniswap V3 on behalf of Vincent Users, enabling integration with decentralized exchanges.
8
4
 
9
5
  ## Features
10
6
 
11
7
  - Execute token swaps on Uniswap V3
12
8
  - Support for exact input and exact output swaps
13
- - Support for multiple token pairs
14
- - Integration with spending limit policies for enhanced security
15
- - Support for multiple chains and Uniswap deployments
9
+ - Support for multi-hop swaps through multiple pools
10
+ - Support for multiple chains that Uniswap V3 is deployed to
16
11
 
17
12
  ## Installation
18
13
 
@@ -22,106 +17,122 @@ npm install @lit-protocol/vincent-ability-uniswap-swap
22
17
 
23
18
  ## Usage
24
19
 
25
- This ability can be used in Vincent apps to execute Uniswap swaps:
20
+ To use the Uniswap Swap Ability, you need to generate a signed swap quote first, then provide it to both the `precheck` and `execute` functions.
26
21
 
27
- ```typescript
28
- import { getVincentAbilityClient } from '@lit-protocol/vincent-app-sdk/abilityClient';
29
- import { bundledVincentAbility } from '@lit-protocol/vincent-ability-uniswap-swap';
22
+ ### 1. Generate a Signed Swap Quote
30
23
 
31
- // One of delegatee signers from your app's Vincent Dashboard
32
- const delegateeSigner = new ethers.Wallet('YOUR_DELEGATEE_PRIVATE_KEY');
24
+ Before executing a swap, you must generate a signed quote using the `getSignedUniswapQuote` function:
33
25
 
34
- // Initialize the Vincent Ability Client
35
- const abilityClient = getVincentAbilityClient({
36
- ethersSigner: delegateeSigner,
37
- bundledVincentAbility,
26
+ ```typescript
27
+ import { LitNodeClient } from '@lit-protocol/lit-node-client';
28
+ import { getSignedUniswapQuote } from '@lit-protocol/vincent-ability-uniswap-swap';
29
+ import { ethers } from 'ethers';
30
+
31
+ // Initialize Lit Node Client
32
+ const litNodeClient = new LitNodeClient({
33
+ litNetwork: 'datil',
34
+ debug: true,
38
35
  });
39
- const delegatorPkpEthAddress = '0x09182301238'; // The delegator PKP Eth Address
40
-
41
- const abilityParams = {
42
- chainId: '8453', // The chain where the tx will be executed
43
- tokenIn: '0x1234...', // The input token address
44
- amountIn: '1000000000000000000', // The input amount (in wei)
45
- tokenOut: '0xabcd...', // The output token address
46
- rpcUrl: 'https://mainnet.base.org', // The RPC to send the transaction through
47
- };
48
-
49
- // Run precheck to see if ability should be executed
50
- const precheckResult = await client.precheck(abilityParams, {
51
- delegatorPkpEthAddress,
36
+ await litNodeClient.connect();
37
+
38
+ // Your delegatee signer (one of the delegatee signers for the Vincent App)
39
+ const delegateeSigner = new ethers.Wallet('YOUR_DELEGATEE_PRIVATE_KEY', provider);
40
+
41
+ // Generate the signed quote
42
+ const signedUniswapQuote = await getSignedUniswapQuote({
43
+ quoteParams: {
44
+ rpcUrl: 'https://mainnet.base.org',
45
+ tokenInAddress: '0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed', // DEGEN
46
+ tokenInAmount: '80', // Amount in token's smallest unit
47
+ tokenOutAddress: '0x4200000000000000000000000000000000000006', // WETH
48
+ recipient: delegatorPkpEthAddress, // The PKP that will execute the swap
49
+ },
50
+ ethersSigner: delegateeSigner,
51
+ litNodeClient,
52
52
  });
53
+ ```
53
54
 
54
- if (precheckResult.success === true) {
55
- // Execute the Vincent Ability
56
- const executeResult = await client.execute(abilityParams, {
57
- delegatorPkpEthAddress,
58
- });
55
+ The return value of `getSignedUniswapQuote` is an object containing:
59
56
 
60
- // ...ability has executed, you can check `executeResult` for details
61
- }
62
- ```
57
+ - `quote`: The Uniswap Quote/Route generated by the V3 SDK using the Alpha Router
58
+ - `signature`: A signature of `quote` signed by a Lit PKP that is configured to only ever be able to sign these generated Uniswap Quotes within the specific Lit Action configured by this Ability
59
+ - `dataSigned`: The data signed by the PKP, an ETH Personal Message containing the hash of the stringified `quote`
60
+ - `signerPublicKey`: The public key of the PKP that signed the `quote`
61
+ - `signerEthAddress`: The Ethereum address of the PKP that signed the `quote`
63
62
 
64
- ## Integration with Policies
63
+ Because the Uniswap SDK makes a lot of RPC calls when generating a quote/route, it exceeded the usage limits of Lit Actions when running within the same Lit Action as the Vincent logic for checking and executing Policies, and verifying on-chain delegation.
65
64
 
66
- This ability is integrated with the Vincent Policy Spending Limit to enforce spending constraints:
65
+ So, the purpose of `getSignedUniswapQuote` is to generate a signed quote/route outside of the Vincent Ability Lit Action, and then provide it to the `precheck` and `execute` functions in a tamper-proof manner. The Vincent Delegatee is unable to modify the quote/route after it has been signed by the PKP, because the Ability verifies the provided route data was signed by the hardcoded PKP address.
66
+
67
+ ### 2. Run Precheck
68
+
69
+ Provide the signed `quote` to `precheck` to check if the swap can be executed:
67
70
 
68
71
  ```typescript
69
- import {
70
- createVincentAbilityPolicy,
71
- createVincentAbility,
72
- createPolicyMapFromAbilityPolicies,
73
- } from '@lit-protocol/vincent-ability-sdk';
74
- import { bundledVincentPolicy } from '@lit-protocol/vincent-policy-spending-limit';
75
- import { abilityParamsSchema } from '@lit-protocol/vincent-ability-uniswap-swap';
76
-
77
- const spendingLimitPolicy = createVincentAbilityPolicy({
78
- abilityParamsSchema,
79
- bundledVincentPolicy,
80
- abilityParameterMappings: {
81
- pkpEthAddress: 'pkpEthAddress',
82
- ethRpcUrl: 'ethRpcUrl',
83
- tokenInAddress: 'tokenAddress',
84
- tokenInDecimals: 'tokenDecimals',
85
- tokenInAmount: 'buyAmount',
86
- },
87
- });
72
+ import { getVincentAbilityClient } from '@lit-protocol/vincent-app-sdk/abilityClient';
73
+ import { bundledVincentAbility } from '@lit-protocol/vincent-ability-uniswap-swap';
88
74
 
89
- export const uniswapSwapWithSpendingLimit = createVincentAbility({
90
- abilityParamsSchema,
91
- policyMap: createPolicyMapFromAbilityPolicies([spendingLimitPolicy]),
92
- // ... rest of ability implementation
75
+ // Initialize the ability client
76
+ const abilityClient = getVincentAbilityClient({
77
+ bundledVincentAbility,
78
+ ethersSigner: delegateeSigner,
93
79
  });
94
- ```
95
80
 
96
- ## Prerequisites
81
+ // Run precheck with the signed quote
82
+ const precheckResult = await abilityClient.precheck(
83
+ {
84
+ rpcUrlForUniswap: 'https://mainnet.base.org',
85
+ signedUniswapQuote: {
86
+ quote: signedUniswapQuote.quote,
87
+ signature: signedUniswapQuote.signature,
88
+ },
89
+ },
90
+ {
91
+ delegatorPkpEthAddress: '0x...', // The delegator PKP ETH address
92
+ },
93
+ );
97
94
 
98
- Before executing a swap, ensure that:
95
+ if (precheckResult.success) {
96
+ console.log('Swap can be executed');
97
+ }
98
+ ```
99
99
 
100
- 1. The user has approved the input token for the Uniswap router
101
- 2. The user has sufficient balance of the input token
102
- 3. The user has delegated permission to the Vincent app to execute swaps
100
+ ### 3. Execute the Swap
103
101
 
104
- You can use the Vincent Ability ERC20 Approval to handle token approvals:
102
+ If `precheck` succeeds, execute the swap using the same signed `quote`:
105
103
 
106
104
  ```typescript
107
- import { getVincentAbilityClient } from '@lit-protocol/vincent-app-sdk/abilityClient';
108
- import { ERC20_APPROVAL_TOOL_IPFS_ID } from '@lit-protocol/vincent-ability-erc20-approval';
105
+ const executeResult = await abilityClient.execute(
106
+ {
107
+ rpcUrlForUniswap: 'https://mainnet.base.org',
108
+ signedUniswapQuote: {
109
+ quote: signedUniswapQuote.quote,
110
+ signature: signedUniswapQuote.signature,
111
+ },
112
+ },
113
+ {
114
+ delegatorPkpEthAddress: '0x...', // The delegator PKP ETH address
115
+ },
116
+ );
109
117
 
110
- // ... approve tokens before swap
118
+ if (executeResult.success) {
119
+ console.log('Swap executed successfully!');
120
+ console.log('Transaction hash:', executeResult.result.swapTxHash);
121
+ }
111
122
  ```
112
123
 
113
- ## Building
114
-
115
- Run `nx build ability-uniswap-swap` to build the library.
124
+ A complete example of generating the signed `quote`, running `precheck`, and executing the swap is available in the `abilities-e2e`'s end-to-end [swap.spec.ts](../abilities-e2e/test-e2e/swap.spec.ts) test.
116
125
 
117
- ## Running unit tests
126
+ ## Development
118
127
 
119
- Run `nx test ability-uniswap-swap` to execute the unit tests via [Jest](https://jestjs.io).
128
+ Because of the need for the `getSignedUniswapQuote` function and it's corresponding Lit Action, included in this package is a script ([create-pkp-for-prepare.js](./scripts/create-pkp-for-prepare.js)) that is used to mint the PKP that is configured to only ever be able to sign these generated Uniswap Quotes within the specific Lit Action configured by this Ability.
120
129
 
121
- ## Contributing
130
+ Anytime changes are made to the [Prepare Lit Action](./src/lib/prepare/lit-action.ts), you **MUST** run the PKP minting script to update the PKP info recorded in [vincent-prepare-metadata.json](./src/generated/vincent-prepare-metadata.json) file. You can execute the script using the Nx target:
122
131
 
123
- Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines on how to contribute to this project.
132
+ ```
133
+ pnpm nx run ability-uniswap-swap:action:create-pkp
134
+ ```
124
135
 
125
- ## License
136
+ This will run the `action:deploy` target, which will build the Prepare Lit Action and deploy it to IPFS, recording the IPFS CID in `vincent-prepare-metadata.json` file. Then the `create-pkp-for-prepare.js` script will be executed minting a new PKP that has the IPFS CID of the Prepare Lit Action as the only permitted Auth Method.
126
137
 
127
- This project is licensed under the MIT License - see the LICENSE file for details.
138
+ After making any changes to the Prepare Lit Action, generating a new signer PKP, run the `build` target to update the Swap Ability Lit Action with the new PKP ETH address used for verifying the `quote` signatures.
package/dist/package.json CHANGED
@@ -1,14 +1,17 @@
1
1
  {
2
2
  "name": "@lit-protocol/vincent-ability-uniswap-swap",
3
- "version": "2.0.1",
3
+ "version": "3.0.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
7
  "dependencies": {
8
- "@lit-protocol/vincent-policy-spending-limit": "workspace:*",
8
+ "@lit-protocol/lit-node-client": "^7.2.3",
9
9
  "@lit-protocol/vincent-ability-sdk": "workspace:*",
10
+ "@lit-protocol/vincent-app-sdk": "workspace:*",
10
11
  "@uniswap/sdk-core": "^7.7.2",
12
+ "@uniswap/smart-order-router": "^4.22.9",
11
13
  "ethers": "^5.8.0",
14
+ "json-stable-stringify": "^1.3.0",
12
15
  "tslib": "2.8.1",
13
16
  "zod": "^3.25.64"
14
17
  },
@@ -20,9 +23,8 @@
20
23
  "@lit-protocol/auth-helpers": "^7.2.3",
21
24
  "@lit-protocol/constants": "^7.2.3",
22
25
  "@lit-protocol/contracts-sdk": "^7.2.3",
23
- "@lit-protocol/lit-node-client": "^7.2.3",
26
+ "@lit-protocol/esbuild-plugin-polyfill-node": "^0.3.0",
24
27
  "esbuild": "^0.19.12",
25
- "esbuild-plugin-polyfill-node": "^0.3.0",
26
28
  "ipfs-only-hash": "^4.0.0",
27
29
  "viem": "^2.28.0"
28
30
  },