@lit-protocol/vincent-policy-spending-limit 0.0.4-mma
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 +14 -0
- package/CONTRIBUTING.md +89 -0
- package/README.md +64 -0
- package/dist/CHANGELOG.md +14 -0
- package/dist/CONTRIBUTING.md +89 -0
- package/dist/README.md +64 -0
- package/dist/package.json +30 -0
- package/dist/src/generated/lit-action.js +9 -0
- package/dist/src/generated/vincent-bundled-policy.d.ts +212 -0
- package/dist/src/generated/vincent-bundled-policy.d.ts.map +1 -0
- package/dist/src/generated/vincent-bundled-policy.js +15 -0
- package/dist/src/generated/vincent-bundled-policy.js.map +1 -0
- package/dist/src/generated/vincent-bundled-policy.ts +13 -0
- package/dist/src/generated/vincent-policy-metadata.json +3 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +9 -0
- package/dist/src/index.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 +12 -0
- package/dist/src/lib/lit-action.js.map +1 -0
- package/dist/src/lib/policy-helpers/calculate-usd-value.d.ts +7 -0
- package/dist/src/lib/policy-helpers/calculate-usd-value.d.ts.map +1 -0
- package/dist/src/lib/policy-helpers/calculate-usd-value.js +22 -0
- package/dist/src/lib/policy-helpers/calculate-usd-value.js.map +1 -0
- package/dist/src/lib/policy-helpers/check-spending-limit.d.ts +16 -0
- package/dist/src/lib/policy-helpers/check-spending-limit.d.ts.map +1 -0
- package/dist/src/lib/policy-helpers/check-spending-limit.js +29 -0
- package/dist/src/lib/policy-helpers/check-spending-limit.js.map +1 -0
- package/dist/src/lib/policy-helpers/get-eth-usd-price.d.ts +6 -0
- package/dist/src/lib/policy-helpers/get-eth-usd-price.d.ts.map +1 -0
- package/dist/src/lib/policy-helpers/get-eth-usd-price.js +22 -0
- package/dist/src/lib/policy-helpers/get-eth-usd-price.js.map +1 -0
- package/dist/src/lib/policy-helpers/get-token-amount-in-usd.d.ts +10 -0
- package/dist/src/lib/policy-helpers/get-token-amount-in-usd.d.ts.map +1 -0
- package/dist/src/lib/policy-helpers/get-token-amount-in-usd.js +68 -0
- package/dist/src/lib/policy-helpers/get-token-amount-in-usd.js.map +1 -0
- package/dist/src/lib/policy-helpers/get-uniswap-quote.d.ts +15 -0
- package/dist/src/lib/policy-helpers/get-uniswap-quote.d.ts.map +1 -0
- package/dist/src/lib/policy-helpers/get-uniswap-quote.js +114 -0
- package/dist/src/lib/policy-helpers/get-uniswap-quote.js.map +1 -0
- package/dist/src/lib/policy-helpers/index.d.ts +7 -0
- package/dist/src/lib/policy-helpers/index.d.ts.map +1 -0
- package/dist/src/lib/policy-helpers/index.js +10 -0
- package/dist/src/lib/policy-helpers/index.js.map +1 -0
- package/dist/src/lib/policy-helpers/send-spend-tx.d.ts +9 -0
- package/dist/src/lib/policy-helpers/send-spend-tx.d.ts.map +1 -0
- package/dist/src/lib/policy-helpers/send-spend-tx.js +144 -0
- package/dist/src/lib/policy-helpers/send-spend-tx.js.map +1 -0
- package/dist/src/lib/policy-helpers/sign-tx.d.ts +3 -0
- package/dist/src/lib/policy-helpers/sign-tx.d.ts.map +1 -0
- package/dist/src/lib/policy-helpers/sign-tx.js +28 -0
- package/dist/src/lib/policy-helpers/sign-tx.js.map +1 -0
- package/dist/src/lib/policy-helpers/spending-limit-contract.d.ts +4 -0
- package/dist/src/lib/policy-helpers/spending-limit-contract.d.ts.map +1 -0
- package/dist/src/lib/policy-helpers/spending-limit-contract.js +22 -0
- package/dist/src/lib/policy-helpers/spending-limit-contract.js.map +1 -0
- package/dist/src/lib/schemas.d.ts +101 -0
- package/dist/src/lib/schemas.d.ts.map +1 -0
- package/dist/src/lib/schemas.js +60 -0
- package/dist/src/lib/schemas.js.map +1 -0
- package/dist/src/lib/vincent-policy.d.ts +209 -0
- package/dist/src/lib/vincent-policy.d.ts.map +1 -0
- package/dist/src/lib/vincent-policy.js +117 -0
- package/dist/src/lib/vincent-policy.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getUniswapQuote = void 0;
|
|
4
|
+
const sdk_core_1 = require("@uniswap/sdk-core");
|
|
5
|
+
const ethers_1 = require("ethers");
|
|
6
|
+
const UNISWAP_V3_QUOTER_INTERFACE = new ethers_1.ethers.utils.Interface([
|
|
7
|
+
'function quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint24 fee, uint160 sqrtPriceLimitX96)) external returns (uint256 amountOut, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)',
|
|
8
|
+
]);
|
|
9
|
+
const getUniswapQuote = async ({ rpcUrl, chainId, tokenInAddress, tokenInDecimals, tokenInAmount, tokenOutAddress, tokenOutDecimals, }) => {
|
|
10
|
+
console.log('Getting Uniswap Quote (getUniswapQuote)', {
|
|
11
|
+
rpcUrl,
|
|
12
|
+
chainId,
|
|
13
|
+
tokenInAddress,
|
|
14
|
+
tokenInDecimals,
|
|
15
|
+
tokenInAmount,
|
|
16
|
+
tokenOutAddress,
|
|
17
|
+
tokenOutDecimals,
|
|
18
|
+
});
|
|
19
|
+
const chainAddressMap = sdk_core_1.CHAIN_TO_ADDRESSES_MAP[chainId];
|
|
20
|
+
if (chainAddressMap === undefined)
|
|
21
|
+
throw new Error(`Unsupported chainId: ${chainId} (getUniswapQuote)`);
|
|
22
|
+
if (chainAddressMap.quoterAddress === undefined)
|
|
23
|
+
throw new Error(`No Uniswap V3 Quoter Address found for chainId: ${chainId} (getUniswapQuote)`);
|
|
24
|
+
const quoterAddress = chainAddressMap.quoterAddress;
|
|
25
|
+
console.log(`Using Quoter Address: ${quoterAddress} (getUniswapQuote)`);
|
|
26
|
+
const uniswapRpcProvider = new ethers_1.ethers.providers.StaticJsonRpcProvider(rpcUrl);
|
|
27
|
+
const formattedTokenInAmount = ethers_1.ethers.utils.parseUnits(tokenInAmount.toString(), tokenInDecimals);
|
|
28
|
+
console.log('Amount conversion:', {
|
|
29
|
+
original: tokenInAmount,
|
|
30
|
+
decimals: tokenInDecimals,
|
|
31
|
+
wei: formattedTokenInAmount.toString(),
|
|
32
|
+
formatted: ethers_1.ethers.utils.formatUnits(formattedTokenInAmount, tokenInDecimals),
|
|
33
|
+
});
|
|
34
|
+
let bestQuote = null;
|
|
35
|
+
let bestFee = null;
|
|
36
|
+
const feeTiers = [3000, 500]; // Supported fee tiers (0.3% and 0.05%)
|
|
37
|
+
for (const fee of feeTiers) {
|
|
38
|
+
try {
|
|
39
|
+
const quoteParams = {
|
|
40
|
+
tokenIn: tokenInAddress,
|
|
41
|
+
tokenOut: tokenOutAddress,
|
|
42
|
+
amountIn: formattedTokenInAmount.toString(),
|
|
43
|
+
fee,
|
|
44
|
+
sqrtPriceLimitX96: 0,
|
|
45
|
+
};
|
|
46
|
+
console.log(`Attempting quote with fee tier ${fee / 10000}% (getUniswapQuote)`);
|
|
47
|
+
console.log('Quote parameters (getUniswapQuote):', quoteParams);
|
|
48
|
+
const quote = await uniswapRpcProvider.call({
|
|
49
|
+
to: quoterAddress,
|
|
50
|
+
data: UNISWAP_V3_QUOTER_INTERFACE.encodeFunctionData('quoteExactInputSingle', [
|
|
51
|
+
quoteParams,
|
|
52
|
+
]),
|
|
53
|
+
});
|
|
54
|
+
console.log('Raw quote response (getUniswapQuote):', quote);
|
|
55
|
+
const [amountOut] = UNISWAP_V3_QUOTER_INTERFACE.decodeFunctionResult('quoteExactInputSingle', quote);
|
|
56
|
+
const currentQuote = ethers_1.ethers.BigNumber.from(amountOut);
|
|
57
|
+
if (currentQuote.isZero()) {
|
|
58
|
+
console.log(`Quote is 0 for fee tier ${fee / 10000}% - skipping (getUniswapQuote)`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const formattedQuote = ethers_1.ethers.utils.formatUnits(currentQuote, tokenOutDecimals);
|
|
62
|
+
console.log(`Quote for fee tier ${fee / 10000}% (getUniswapQuote):`, {
|
|
63
|
+
raw: currentQuote.toString(),
|
|
64
|
+
formatted: formattedQuote,
|
|
65
|
+
});
|
|
66
|
+
if (!bestQuote || currentQuote.gt(bestQuote)) {
|
|
67
|
+
bestQuote = currentQuote;
|
|
68
|
+
bestFee = fee;
|
|
69
|
+
console.log(`New best quote found with fee tier ${fee / 10000}% (getUniswapQuote): ${formattedQuote}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
const err = error;
|
|
74
|
+
// Check if this is an ethers contract error with expected properties
|
|
75
|
+
if ('reason' in err && 'message' in err && 'code' in err) {
|
|
76
|
+
if (err.reason === 'Unexpected error') {
|
|
77
|
+
console.log(`Unexpected error thrown, probably no pool found for fee tier ${fee / 10000}% (getUniswapQuote)`, err);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
console.log(`Quoter call failed for fee tier ${fee / 10000}% (getUniswapQuote)`, {
|
|
81
|
+
message: err.message,
|
|
82
|
+
reason: err.reason,
|
|
83
|
+
code: err.code,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (!bestQuote || !bestFee) {
|
|
94
|
+
throw new Error('Failed to get quote from Uniswap V3. No valid pool found for this token pair or quote returned 0 (getUniswapQuote)');
|
|
95
|
+
}
|
|
96
|
+
// Calculate minimum output with 0.5% slippage tolerance
|
|
97
|
+
const slippageTolerance = 0.005;
|
|
98
|
+
const amountOutMin = bestQuote.mul(1000 - slippageTolerance * 1000).div(1000);
|
|
99
|
+
console.log('Final quote details:', {
|
|
100
|
+
bestFee: `${bestFee / 10000}%`,
|
|
101
|
+
bestQuote: {
|
|
102
|
+
raw: bestQuote.toString(),
|
|
103
|
+
formatted: ethers_1.ethers.utils.formatUnits(bestQuote, tokenOutDecimals),
|
|
104
|
+
},
|
|
105
|
+
minimumOutput: {
|
|
106
|
+
raw: amountOutMin.toString(),
|
|
107
|
+
formatted: ethers_1.ethers.utils.formatUnits(amountOutMin, tokenOutDecimals),
|
|
108
|
+
},
|
|
109
|
+
slippageTolerance: `${slippageTolerance * 100}%`,
|
|
110
|
+
});
|
|
111
|
+
return { bestQuote, bestFee, amountOutMin };
|
|
112
|
+
};
|
|
113
|
+
exports.getUniswapQuote = getUniswapQuote;
|
|
114
|
+
//# sourceMappingURL=get-uniswap-quote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-uniswap-quote.js","sourceRoot":"","sources":["../../../../src/lib/policy-helpers/get-uniswap-quote.ts"],"names":[],"mappings":";;;AAAA,gDAA2D;AAC3D,mCAAgC;AAEhC,MAAM,2BAA2B,GAAG,IAAI,eAAM,CAAC,KAAK,CAAC,SAAS,CAAC;IAC7D,mPAAmP;CACpP,CAAC,CAAC;AAEI,MAAM,eAAe,GAAG,KAAK,EAAE,EACpC,MAAM,EACN,OAAO,EACP,cAAc,EACd,eAAe,EACf,aAAa,EACb,eAAe,EACf,gBAAgB,GASjB,EAIE,EAAE;IACH,OAAO,CAAC,GAAG,CAAC,yCAAyC,EAAE;QACrD,MAAM;QACN,OAAO;QACP,cAAc;QACd,eAAe;QACf,aAAa;QACb,eAAe;QACf,gBAAgB;KACjB,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,iCAAsB,CAAC,OAA8C,CAAC,CAAC;IAC/F,IAAI,eAAe,KAAK,SAAS;QAC/B,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,oBAAoB,CAAC,CAAC;IACvE,IAAI,eAAe,CAAC,aAAa,KAAK,SAAS;QAC7C,MAAM,IAAI,KAAK,CAAC,mDAAmD,OAAO,oBAAoB,CAAC,CAAC;IAClG,MAAM,aAAa,GAAG,eAAe,CAAC,aAA8B,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,yBAAyB,aAAa,oBAAoB,CAAC,CAAC;IAExE,MAAM,kBAAkB,GAAG,IAAI,eAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAE9E,MAAM,sBAAsB,GAAG,eAAM,CAAC,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,QAAQ,EAAE,EAAE,eAAe,CAAC,CAAC;IAClG,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE;QAChC,QAAQ,EAAE,aAAa;QACvB,QAAQ,EAAE,eAAe;QACzB,GAAG,EAAE,sBAAsB,CAAC,QAAQ,EAAE;QACtC,SAAS,EAAE,eAAM,CAAC,KAAK,CAAC,WAAW,CAAC,sBAAsB,EAAE,eAAe,CAAC;KAC7E,CAAC,CAAC;IAEH,IAAI,SAAS,GAAG,IAAI,CAAC;IACrB,IAAI,OAAO,GAAG,IAAI,CAAC;IAEnB,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,uCAAuC;IACrE,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,WAAW,GAAG;gBAClB,OAAO,EAAE,cAAc;gBACvB,QAAQ,EAAE,eAAe;gBACzB,QAAQ,EAAE,sBAAsB,CAAC,QAAQ,EAAE;gBAC3C,GAAG;gBACH,iBAAiB,EAAE,CAAC;aACrB,CAAC;YAEF,OAAO,CAAC,GAAG,CAAC,kCAAkC,GAAG,GAAG,KAAK,qBAAqB,CAAC,CAAC;YAChF,OAAO,CAAC,GAAG,CAAC,qCAAqC,EAAE,WAAW,CAAC,CAAC;YAEhE,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC;gBAC1C,EAAE,EAAE,aAAa;gBACjB,IAAI,EAAE,2BAA2B,CAAC,kBAAkB,CAAC,uBAAuB,EAAE;oBAC5E,WAAW;iBACZ,CAAC;aACH,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;YAE5D,MAAM,CAAC,SAAS,CAAC,GAAG,2BAA2B,CAAC,oBAAoB,CAClE,uBAAuB,EACvB,KAAK,CACN,CAAC;YAEF,MAAM,YAAY,GAAG,eAAM,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtD,IAAI,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,GAAG,KAAK,gCAAgC,CAAC,CAAC;gBACpF,SAAS;YACX,CAAC;YAED,MAAM,cAAc,GAAG,eAAM,CAAC,KAAK,CAAC,WAAW,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;YAChF,OAAO,CAAC,GAAG,CAAC,sBAAsB,GAAG,GAAG,KAAK,sBAAsB,EAAE;gBACnE,GAAG,EAAE,YAAY,CAAC,QAAQ,EAAE;gBAC5B,SAAS,EAAE,cAAc;aAC1B,CAAC,CAAC;YAEH,IAAI,CAAC,SAAS,IAAI,YAAY,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC7C,SAAS,GAAG,YAAY,CAAC;gBACzB,OAAO,GAAG,GAAG,CAAC;gBACd,OAAO,CAAC,GAAG,CACT,sCAAsC,GAAG,GAAG,KAAK,wBAAwB,cAAc,EAAE,CAC1F,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,KAA6D,CAAC;YAE1E,qEAAqE;YACrE,IAAI,QAAQ,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;gBACzD,IAAI,GAAG,CAAC,MAAM,KAAK,kBAAkB,EAAE,CAAC;oBACtC,OAAO,CAAC,GAAG,CACT,gEAAgE,GAAG,GAAG,KAAK,qBAAqB,EAChG,GAAG,CACJ,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,mCAAmC,GAAG,GAAG,KAAK,qBAAqB,EAAE;wBAC/E,OAAO,EAAE,GAAG,CAAC,OAAO;wBACpB,MAAM,EAAE,GAAG,CAAC,MAAM;wBAClB,IAAI,EAAE,GAAG,CAAC,IAAI;qBACf,CAAC,CAAC;gBACL,CAAC;gBAED,SAAS;YACX,CAAC;iBAAM,CAAC;gBACN,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,oHAAoH,CACrH,CAAC;IACJ,CAAC;IAED,wDAAwD;IACxD,MAAM,iBAAiB,GAAG,KAAK,CAAC;IAChC,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,iBAAiB,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE;QAClC,OAAO,EAAE,GAAG,OAAO,GAAG,KAAK,GAAG;QAC9B,SAAS,EAAE;YACT,GAAG,EAAE,SAAS,CAAC,QAAQ,EAAE;YACzB,SAAS,EAAE,eAAM,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,gBAAgB,CAAC;SACjE;QACD,aAAa,EAAE;YACb,GAAG,EAAE,YAAY,CAAC,QAAQ,EAAE;YAC5B,SAAS,EAAE,eAAM,CAAC,KAAK,CAAC,WAAW,CAAC,YAAY,EAAE,gBAAgB,CAAC;SACpE;QACD,iBAAiB,EAAE,GAAG,iBAAiB,GAAG,GAAG,GAAG;KACjD,CAAC,CAAC;IAEH,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AAC9C,CAAC,CAAC;AAlJW,QAAA,eAAe,mBAkJ1B"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './get-token-amount-in-usd';
|
|
2
|
+
export * from './get-uniswap-quote';
|
|
3
|
+
export * from './send-spend-tx';
|
|
4
|
+
export * from './sign-tx';
|
|
5
|
+
export * from './check-spending-limit';
|
|
6
|
+
export * from './spending-limit-contract';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/policy-helpers/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./get-token-amount-in-usd"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./get-uniswap-quote"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./send-spend-tx"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./sign-tx"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./check-spending-limit"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./spending-limit-contract"), exports);
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/policy-helpers/index.ts"],"names":[],"mappings":";;;AAAA,oEAA0C;AAC1C,8DAAoC;AACpC,0DAAgC;AAChC,oDAA0B;AAC1B,iEAAuC;AACvC,oEAA0C"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const sendSpendTx: ({ appId, amountSpentUsd, maxSpendingLimitInUsd, spendingLimitDuration, pkpEthAddress, pkpPubKey, }: {
|
|
2
|
+
appId: number;
|
|
3
|
+
amountSpentUsd: number;
|
|
4
|
+
maxSpendingLimitInUsd: number;
|
|
5
|
+
spendingLimitDuration: number;
|
|
6
|
+
pkpEthAddress: string;
|
|
7
|
+
pkpPubKey: string;
|
|
8
|
+
}) => Promise<any>;
|
|
9
|
+
//# sourceMappingURL=send-spend-tx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send-spend-tx.d.ts","sourceRoot":"","sources":["../../../../src/lib/policy-helpers/send-spend-tx.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,WAAW,GAAU,oGAO/B;IACD,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB,iBAqGA,CAAC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sendSpendTx = void 0;
|
|
4
|
+
const ethers_1 = require("ethers");
|
|
5
|
+
const spending_limit_contract_1 = require("./spending-limit-contract");
|
|
6
|
+
const sign_tx_1 = require("./sign-tx");
|
|
7
|
+
const sendSpendTx = async ({ appId, amountSpentUsd, maxSpendingLimitInUsd, spendingLimitDuration, pkpEthAddress, pkpPubKey, }) => {
|
|
8
|
+
const spendingLimitContract = (0, spending_limit_contract_1.getSpendingLimitContractInstance)();
|
|
9
|
+
const buildPartialSpendTxResponse = await Lit.Actions.runOnce({ waitForResponse: true, name: 'send spend tx gas estimation' }, async () => {
|
|
10
|
+
console.log(`Preparing transaction to send to Spending Limit Contract: ${spending_limit_contract_1.SPENDING_LIMIT_CONTRACT_ADDRESS} (sendSpendTx)`);
|
|
11
|
+
try {
|
|
12
|
+
console.log(`Estimating gas for spending limit transaction...`);
|
|
13
|
+
// Get current gas price and nonce
|
|
14
|
+
const [feeData, nonce] = await Promise.all([
|
|
15
|
+
spendingLimitContract.provider.getFeeData(),
|
|
16
|
+
spendingLimitContract.provider.getTransactionCount(pkpEthAddress),
|
|
17
|
+
]);
|
|
18
|
+
// Encode function data
|
|
19
|
+
const txData = spendingLimitContract.interface.encodeFunctionData('spend', [
|
|
20
|
+
BigInt(appId),
|
|
21
|
+
BigInt(amountSpentUsd),
|
|
22
|
+
BigInt(maxSpendingLimitInUsd),
|
|
23
|
+
BigInt(spendingLimitDuration),
|
|
24
|
+
]);
|
|
25
|
+
// Estimate gas
|
|
26
|
+
const estimatedGas = await spendingLimitContract.estimateGas.spend(BigInt(appId), BigInt(amountSpentUsd), BigInt(maxSpendingLimitInUsd), BigInt(spendingLimitDuration), { from: pkpEthAddress });
|
|
27
|
+
console.log('fetching nonce for pkpEthAddress: ', pkpEthAddress, ' (sendSpendTx)');
|
|
28
|
+
return JSON.stringify({
|
|
29
|
+
status: 'success',
|
|
30
|
+
data: txData,
|
|
31
|
+
gasLimit: estimatedGas.toString(),
|
|
32
|
+
maxFeePerGas: feeData.maxFeePerGas?.toString() || '0',
|
|
33
|
+
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas?.toString() || '0',
|
|
34
|
+
nonce: nonce.toString(),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
return attemptToDecodeSpendLimitExceededError(error, spendingLimitContract);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const parsedBuildPartialSpendTxResponse = JSON.parse(buildPartialSpendTxResponse);
|
|
42
|
+
if (parsedBuildPartialSpendTxResponse.status === 'error') {
|
|
43
|
+
throw new Error(`Error estimating gas for spending limit transaction: ${parsedBuildPartialSpendTxResponse.error}`);
|
|
44
|
+
}
|
|
45
|
+
const { gasLimit, maxFeePerGas, maxPriorityFeePerGas, nonce, data } = parsedBuildPartialSpendTxResponse;
|
|
46
|
+
// Create ethers Transaction object
|
|
47
|
+
const unsignedSpendTx = {
|
|
48
|
+
to: spending_limit_contract_1.SPENDING_LIMIT_CONTRACT_ADDRESS,
|
|
49
|
+
data: data,
|
|
50
|
+
value: ethers_1.ethers.BigNumber.from(0),
|
|
51
|
+
gasLimit: ethers_1.ethers.BigNumber.from(gasLimit),
|
|
52
|
+
maxFeePerGas: ethers_1.ethers.BigNumber.from(maxFeePerGas),
|
|
53
|
+
maxPriorityFeePerGas: ethers_1.ethers.BigNumber.from(maxPriorityFeePerGas),
|
|
54
|
+
nonce: Number(nonce),
|
|
55
|
+
chainId: 175188,
|
|
56
|
+
type: 2, // EIP-1559 transaction type
|
|
57
|
+
};
|
|
58
|
+
console.log(`Signing spend transaction: ${safeStringify(unsignedSpendTx)} (sendSpendTx)`);
|
|
59
|
+
const signedSpendTx = await (0, sign_tx_1.signTx)(pkpPubKey, unsignedSpendTx, 'spendingLimitSig');
|
|
60
|
+
console.log(`Broadcasting spend transaction...`);
|
|
61
|
+
const spendTxResponse = await Lit.Actions.runOnce({ waitForResponse: true, name: 'spendTxSender' }, async () => {
|
|
62
|
+
try {
|
|
63
|
+
const txResponse = await spendingLimitContract.provider.sendTransaction(signedSpendTx);
|
|
64
|
+
return JSON.stringify({
|
|
65
|
+
status: 'success',
|
|
66
|
+
txHash: txResponse.hash,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
return attemptToDecodeSpendLimitExceededError(error, spendingLimitContract);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
console.log(`Spend transaction response: ${spendTxResponse} (sendSpendTx)`);
|
|
74
|
+
const parsedSpendTxResponse = JSON.parse(spendTxResponse);
|
|
75
|
+
if (parsedSpendTxResponse.status === 'error') {
|
|
76
|
+
throw new Error(`Error sending spend transaction: ${parsedSpendTxResponse.error}`);
|
|
77
|
+
}
|
|
78
|
+
return parsedSpendTxResponse.txHash;
|
|
79
|
+
};
|
|
80
|
+
exports.sendSpendTx = sendSpendTx;
|
|
81
|
+
const safeStringify = (obj) => {
|
|
82
|
+
return JSON.stringify(obj, (_, value) => {
|
|
83
|
+
if (typeof value === 'bigint') {
|
|
84
|
+
return value.toString();
|
|
85
|
+
}
|
|
86
|
+
if (ethers_1.ethers.BigNumber.isBigNumber(value)) {
|
|
87
|
+
return value.toString();
|
|
88
|
+
}
|
|
89
|
+
return value;
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
const attemptToDecodeSpendLimitExceededError = (error, contract) => {
|
|
93
|
+
try {
|
|
94
|
+
// Check if it's an ethers revert error with data
|
|
95
|
+
if (error && typeof error === 'object' && 'reason' in error) {
|
|
96
|
+
const ethersError = error;
|
|
97
|
+
// Try to decode custom error from error data
|
|
98
|
+
if (ethersError.data) {
|
|
99
|
+
try {
|
|
100
|
+
const decoded = contract.interface.parseError(ethersError.data);
|
|
101
|
+
if (decoded.name === 'SpendLimitExceeded' && decoded.args) {
|
|
102
|
+
const [user, appId, amount, limit] = decoded.args;
|
|
103
|
+
return JSON.stringify({
|
|
104
|
+
status: 'error',
|
|
105
|
+
error: `Spending limit exceeded. User: ${user}, App ID: ${appId.toString()}, Attempted spend amount: ${amount.toString()}, Daily spend limit: ${limit.toString()}`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (parseError) {
|
|
110
|
+
// If parsing fails, fall through to generic error handling
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Handle standard revert with reason string
|
|
114
|
+
if (ethersError.reason) {
|
|
115
|
+
return JSON.stringify({
|
|
116
|
+
status: 'error',
|
|
117
|
+
error: `Contract reverted: ${ethersError.reason}`,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Handle ethers CALL_EXCEPTION errors
|
|
122
|
+
if (error && typeof error === 'object' && 'code' in error) {
|
|
123
|
+
const ethersError = error;
|
|
124
|
+
if (ethersError.code === 'CALL_EXCEPTION' && ethersError.errorArgs) {
|
|
125
|
+
const [user, appId, amount, limit] = ethersError.errorArgs;
|
|
126
|
+
return JSON.stringify({
|
|
127
|
+
status: 'error',
|
|
128
|
+
error: `Spending limit exceeded. User: ${user}, App ID: ${appId.toString()}, Attempted spend amount: ${amount.toString()}, Daily spend limit: ${limit.toString()}`,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch (decodingError) {
|
|
134
|
+
return JSON.stringify({
|
|
135
|
+
status: 'error',
|
|
136
|
+
error: `Failed to decode revert reason: ${decodingError}`,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return JSON.stringify({
|
|
140
|
+
status: 'error',
|
|
141
|
+
error: error?.toString() || 'Unknown error',
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
//# sourceMappingURL=send-spend-tx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send-spend-tx.js","sourceRoot":"","sources":["../../../../src/lib/policy-helpers/send-spend-tx.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign-tx.d.ts","sourceRoot":"","sources":["../../../../src/lib/policy-helpers/sign-tx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAYhC,eAAO,MAAM,MAAM,GAAU,cAAc,MAAM,EAAE,IAAI,MAAM,CAAC,WAAW,EAAE,SAAS,MAAM,oBA2BzF,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.signTx = void 0;
|
|
4
|
+
const ethers_1 = require("ethers");
|
|
5
|
+
const signTx = async (pkpPublicKey, tx, sigName) => {
|
|
6
|
+
// Remove 0x prefix if it exists, Lit expects a hex string without 0x prefix
|
|
7
|
+
const publicKeyForLit = pkpPublicKey.replace(/^0x/, '');
|
|
8
|
+
console.log(`Signing using PKP Public Key: ${publicKeyForLit} (signTx)`);
|
|
9
|
+
const unsignedSerializedTx = ethers_1.ethers.utils.serializeTransaction(tx);
|
|
10
|
+
const txHash = ethers_1.ethers.utils.keccak256(unsignedSerializedTx);
|
|
11
|
+
console.log('Tx hash (signTx)', txHash);
|
|
12
|
+
const signatureResponse = await Lit.Actions.signAndCombineEcdsa({
|
|
13
|
+
toSign: ethers_1.ethers.utils.arrayify(txHash),
|
|
14
|
+
publicKey: publicKeyForLit,
|
|
15
|
+
sigName,
|
|
16
|
+
});
|
|
17
|
+
const { r, s, v } = JSON.parse(signatureResponse);
|
|
18
|
+
const ethersJoinedSignature = ethers_1.ethers.utils.joinSignature({
|
|
19
|
+
r: '0x' + r.substring(2),
|
|
20
|
+
s: '0x' + s,
|
|
21
|
+
v: v,
|
|
22
|
+
});
|
|
23
|
+
const signedSerializedTx = ethers_1.ethers.utils.serializeTransaction(tx, ethersJoinedSignature);
|
|
24
|
+
console.log('Signed serialized tx (signTx)', signedSerializedTx);
|
|
25
|
+
return signedSerializedTx;
|
|
26
|
+
};
|
|
27
|
+
exports.signTx = signTx;
|
|
28
|
+
//# sourceMappingURL=sign-tx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign-tx.js","sourceRoot":"","sources":["../../../../src/lib/policy-helpers/sign-tx.ts"],"names":[],"mappings":";;;AAAA,mCAAgC;AAYzB,MAAM,MAAM,GAAG,KAAK,EAAE,YAAoB,EAAE,EAAsB,EAAE,OAAe,EAAE,EAAE;IAC5F,4EAA4E;IAC5E,MAAM,eAAe,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,iCAAiC,eAAe,WAAW,CAAC,CAAC;IAEzE,MAAM,oBAAoB,GAAG,eAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;IAEnE,MAAM,MAAM,GAAG,eAAM,CAAC,KAAK,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;IAExC,MAAM,iBAAiB,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC;QAC9D,MAAM,EAAE,eAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QACrC,SAAS,EAAE,eAAe;QAC1B,OAAO;KACR,CAAC,CAAC;IAEH,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAClD,MAAM,qBAAqB,GAAG,eAAM,CAAC,KAAK,CAAC,aAAa,CAAC;QACvD,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QACxB,CAAC,EAAE,IAAI,GAAG,CAAC;QACX,CAAC,EAAE,CAAC;KACL,CAAC,CAAC;IAEH,MAAM,kBAAkB,GAAG,eAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC;IACxF,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,kBAAkB,CAAC,CAAC;IAEjE,OAAO,kBAAkB,CAAC;AAC5B,CAAC,CAAC;AA3BW,QAAA,MAAM,UA2BjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spending-limit-contract.d.ts","sourceRoot":"","sources":["../../../../src/lib/policy-helpers/spending-limit-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAkBhC,eAAO,MAAM,+BAA+B,+CAA+C,CAAC;AAE5F,eAAO,MAAM,gCAAgC,uBAM5C,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSpendingLimitContractInstance = exports.SPENDING_LIMIT_CONTRACT_ADDRESS = void 0;
|
|
4
|
+
const ethers_1 = require("ethers");
|
|
5
|
+
const SPENDING_LIMIT_CONTRACT_ABI = [
|
|
6
|
+
'event Spent(address indexed spender, uint256 indexed appId, uint256 amount, uint256 timestamp)',
|
|
7
|
+
'error EmptyAppIdsArray(address user)',
|
|
8
|
+
'error SpendLimitExceeded(address user, uint256 appId, uint256 amount, uint256 limit)',
|
|
9
|
+
'error ZeroAppIdNotAllowed(address user)',
|
|
10
|
+
'error ZeroDurationQuery(address user)',
|
|
11
|
+
'function checkLimit(address user, uint256 appId, uint256 amountToSpend, uint256 userMaxSpendLimit, uint256 duration) view returns (bool)',
|
|
12
|
+
'function getAppSpendHistory(address user, uint256 appId, uint256 duration) view returns ((uint256 timestamp, uint256 runningSpend)[] history)',
|
|
13
|
+
'function getAppsSpentInDuration(address user, uint256[] appIds, uint256 duration) view returns (uint256)',
|
|
14
|
+
'function getTotalSpent(address user, uint256 duration) view returns (uint256)',
|
|
15
|
+
'function spend(uint256 appId, uint256 amount, uint256 userMaxSpendLimit, uint256 duration)',
|
|
16
|
+
];
|
|
17
|
+
exports.SPENDING_LIMIT_CONTRACT_ADDRESS = '0x756fa449de893446b26e10c6c66e62ccabee908c';
|
|
18
|
+
const getSpendingLimitContractInstance = () => {
|
|
19
|
+
return new ethers_1.ethers.Contract(exports.SPENDING_LIMIT_CONTRACT_ADDRESS, SPENDING_LIMIT_CONTRACT_ABI, new ethers_1.ethers.providers.StaticJsonRpcProvider('https://yellowstone-rpc.litprotocol.com/'));
|
|
20
|
+
};
|
|
21
|
+
exports.getSpendingLimitContractInstance = getSpendingLimitContractInstance;
|
|
22
|
+
//# sourceMappingURL=spending-limit-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spending-limit-contract.js","sourceRoot":"","sources":["../../../../src/lib/policy-helpers/spending-limit-contract.ts"],"names":[],"mappings":";;;AAAA,mCAAgC;AAEhC,MAAM,2BAA2B,GAAG;IAClC,gGAAgG;IAEhG,sCAAsC;IACtC,sFAAsF;IACtF,yCAAyC;IACzC,uCAAuC;IAEvC,0IAA0I;IAC1I,+IAA+I;IAC/I,0GAA0G;IAC1G,+EAA+E;IAE/E,4FAA4F;CACpF,CAAC;AAEE,QAAA,+BAA+B,GAAG,4CAA4C,CAAC;AAErF,MAAM,gCAAgC,GAAG,GAAG,EAAE;IACnD,OAAO,IAAI,eAAM,CAAC,QAAQ,CACxB,uCAA+B,EAC/B,2BAA2B,EAC3B,IAAI,eAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC,0CAA0C,CAAC,CACvF,CAAC;AACJ,CAAC,CAAC;AANW,QAAA,gCAAgC,oCAM3C"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const toolParamsSchema: z.ZodObject<{
|
|
3
|
+
ethRpcUrl: z.ZodString;
|
|
4
|
+
rpcUrlForUniswap: z.ZodString;
|
|
5
|
+
chainIdForUniswap: z.ZodNumber;
|
|
6
|
+
tokenAddress: z.ZodString;
|
|
7
|
+
tokenDecimals: z.ZodNumber;
|
|
8
|
+
buyAmount: z.ZodNumber;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
ethRpcUrl: string;
|
|
11
|
+
rpcUrlForUniswap: string;
|
|
12
|
+
chainIdForUniswap: number;
|
|
13
|
+
tokenAddress: string;
|
|
14
|
+
tokenDecimals: number;
|
|
15
|
+
buyAmount: number;
|
|
16
|
+
}, {
|
|
17
|
+
ethRpcUrl: string;
|
|
18
|
+
rpcUrlForUniswap: string;
|
|
19
|
+
chainIdForUniswap: number;
|
|
20
|
+
tokenAddress: string;
|
|
21
|
+
tokenDecimals: number;
|
|
22
|
+
buyAmount: number;
|
|
23
|
+
}>;
|
|
24
|
+
export declare const userParamsSchema: z.ZodObject<{
|
|
25
|
+
maxDailySpendingLimitInUsdCents: z.ZodBigInt;
|
|
26
|
+
}, "strip", z.ZodTypeAny, {
|
|
27
|
+
maxDailySpendingLimitInUsdCents: bigint;
|
|
28
|
+
}, {
|
|
29
|
+
maxDailySpendingLimitInUsdCents: bigint;
|
|
30
|
+
}>;
|
|
31
|
+
export declare const precheckAllowResultSchema: z.ZodObject<{
|
|
32
|
+
maxSpendingLimitInUsd: z.ZodNumber;
|
|
33
|
+
buyAmountInUsd: z.ZodNumber;
|
|
34
|
+
}, "strip", z.ZodTypeAny, {
|
|
35
|
+
maxSpendingLimitInUsd: number;
|
|
36
|
+
buyAmountInUsd: number;
|
|
37
|
+
}, {
|
|
38
|
+
maxSpendingLimitInUsd: number;
|
|
39
|
+
buyAmountInUsd: number;
|
|
40
|
+
}>;
|
|
41
|
+
export declare const precheckDenyResultSchema: z.ZodObject<{
|
|
42
|
+
reason: z.ZodLiteral<"Attempted buy amount exceeds daily limit">;
|
|
43
|
+
maxSpendingLimitInUsd: z.ZodNumber;
|
|
44
|
+
buyAmountInUsd: z.ZodNumber;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
maxSpendingLimitInUsd: number;
|
|
47
|
+
reason: "Attempted buy amount exceeds daily limit";
|
|
48
|
+
buyAmountInUsd: number;
|
|
49
|
+
}, {
|
|
50
|
+
maxSpendingLimitInUsd: number;
|
|
51
|
+
reason: "Attempted buy amount exceeds daily limit";
|
|
52
|
+
buyAmountInUsd: number;
|
|
53
|
+
}>;
|
|
54
|
+
export declare const evalAllowResultSchema: z.ZodObject<{
|
|
55
|
+
maxSpendingLimitInUsd: z.ZodNumber;
|
|
56
|
+
buyAmountInUsd: z.ZodNumber;
|
|
57
|
+
}, "strip", z.ZodTypeAny, {
|
|
58
|
+
maxSpendingLimitInUsd: number;
|
|
59
|
+
buyAmountInUsd: number;
|
|
60
|
+
}, {
|
|
61
|
+
maxSpendingLimitInUsd: number;
|
|
62
|
+
buyAmountInUsd: number;
|
|
63
|
+
}>;
|
|
64
|
+
export declare const evalDenyResultSchema: z.ZodObject<{
|
|
65
|
+
reason: z.ZodString;
|
|
66
|
+
maxSpendingLimitInUsd: z.ZodOptional<z.ZodNumber>;
|
|
67
|
+
buyAmountInUsd: z.ZodOptional<z.ZodNumber>;
|
|
68
|
+
}, "strip", z.ZodTypeAny, {
|
|
69
|
+
reason: string;
|
|
70
|
+
maxSpendingLimitInUsd?: number | undefined;
|
|
71
|
+
buyAmountInUsd?: number | undefined;
|
|
72
|
+
}, {
|
|
73
|
+
reason: string;
|
|
74
|
+
maxSpendingLimitInUsd?: number | undefined;
|
|
75
|
+
buyAmountInUsd?: number | undefined;
|
|
76
|
+
}>;
|
|
77
|
+
export declare const commitParamsSchema: z.ZodObject<{
|
|
78
|
+
amountSpentUsd: z.ZodNumber;
|
|
79
|
+
maxSpendingLimitInUsd: z.ZodNumber;
|
|
80
|
+
}, "strip", z.ZodTypeAny, {
|
|
81
|
+
amountSpentUsd: number;
|
|
82
|
+
maxSpendingLimitInUsd: number;
|
|
83
|
+
}, {
|
|
84
|
+
amountSpentUsd: number;
|
|
85
|
+
maxSpendingLimitInUsd: number;
|
|
86
|
+
}>;
|
|
87
|
+
export declare const commitAllowResultSchema: z.ZodObject<{
|
|
88
|
+
spendTxHash: z.ZodString;
|
|
89
|
+
}, "strip", z.ZodTypeAny, {
|
|
90
|
+
spendTxHash: string;
|
|
91
|
+
}, {
|
|
92
|
+
spendTxHash: string;
|
|
93
|
+
}>;
|
|
94
|
+
export declare const commitDenyResultSchema: z.ZodObject<{
|
|
95
|
+
error: z.ZodString;
|
|
96
|
+
}, "strip", z.ZodTypeAny, {
|
|
97
|
+
error: string;
|
|
98
|
+
}, {
|
|
99
|
+
error: string;
|
|
100
|
+
}>;
|
|
101
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/lib/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;EAyB3B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;EAI3B,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;EAGpC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;EAMnC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;EAGhC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;EAI/B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;EAG7B,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;EAElC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;EAEjC,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.commitDenyResultSchema = exports.commitAllowResultSchema = exports.commitParamsSchema = exports.evalDenyResultSchema = exports.evalAllowResultSchema = exports.precheckDenyResultSchema = exports.precheckAllowResultSchema = exports.userParamsSchema = exports.toolParamsSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.toolParamsSchema = zod_1.z.object({
|
|
6
|
+
ethRpcUrl: zod_1.z
|
|
7
|
+
.string()
|
|
8
|
+
.describe('An Ethereum Mainnet RPC Endpoint. This is used to check USD <> ETH prices via Chainlink.'),
|
|
9
|
+
rpcUrlForUniswap: zod_1.z
|
|
10
|
+
.string()
|
|
11
|
+
.describe('An RPC endpoint for any chain that is supported by the Uniswap. Must work for the chain specified in chainIdForUniswap.'),
|
|
12
|
+
chainIdForUniswap: zod_1.z
|
|
13
|
+
.number()
|
|
14
|
+
.describe('The chain ID to execute the transaction on. For example: 8453 for Base.'),
|
|
15
|
+
tokenAddress: zod_1.z
|
|
16
|
+
.string()
|
|
17
|
+
.describe('ERC20 Token address to spend/sell. For example 0x4200000000000000000000000000000000000006 for WETH on Base.'),
|
|
18
|
+
tokenDecimals: zod_1.z
|
|
19
|
+
.number()
|
|
20
|
+
.describe('ERC20 Token to spend/sell decimals. For example 18 for WETH on Base.'),
|
|
21
|
+
buyAmount: zod_1.z
|
|
22
|
+
.number()
|
|
23
|
+
.describe('Amount of token to spend/sell. For example 0.00001 for 0.00001 WETH.'),
|
|
24
|
+
});
|
|
25
|
+
exports.userParamsSchema = zod_1.z.object({
|
|
26
|
+
maxDailySpendingLimitInUsdCents: zod_1.z
|
|
27
|
+
.bigint()
|
|
28
|
+
.describe('The maximum daily spending limit in USD cents, as a BigInt.'),
|
|
29
|
+
});
|
|
30
|
+
exports.precheckAllowResultSchema = zod_1.z.object({
|
|
31
|
+
maxSpendingLimitInUsd: zod_1.z.number().describe("The user's daily spending limit in USD."),
|
|
32
|
+
buyAmountInUsd: zod_1.z.number().describe('The value of the tokens to be spent, in USD.'),
|
|
33
|
+
});
|
|
34
|
+
exports.precheckDenyResultSchema = zod_1.z.object({
|
|
35
|
+
reason: zod_1.z
|
|
36
|
+
.literal('Attempted buy amount exceeds daily limit')
|
|
37
|
+
.describe('The reason for denying the precheck.'),
|
|
38
|
+
maxSpendingLimitInUsd: zod_1.z.number().describe("The user's daily spending limit in USD."),
|
|
39
|
+
buyAmountInUsd: zod_1.z.number().describe('The value of the tokens to be spent, in USD.'),
|
|
40
|
+
});
|
|
41
|
+
exports.evalAllowResultSchema = zod_1.z.object({
|
|
42
|
+
maxSpendingLimitInUsd: zod_1.z.number().describe("The user's daily spending limit in USD."),
|
|
43
|
+
buyAmountInUsd: zod_1.z.number().describe('The value of the tokens to be spent, in USD.'),
|
|
44
|
+
});
|
|
45
|
+
exports.evalDenyResultSchema = zod_1.z.object({
|
|
46
|
+
reason: zod_1.z.string().describe('The reason for denying the evaluation.'),
|
|
47
|
+
maxSpendingLimitInUsd: zod_1.z.number().optional().describe("The user's daily spending limit in USD."),
|
|
48
|
+
buyAmountInUsd: zod_1.z.number().optional().describe('The value of the tokens to be spent, in USD.'),
|
|
49
|
+
});
|
|
50
|
+
exports.commitParamsSchema = zod_1.z.object({
|
|
51
|
+
amountSpentUsd: zod_1.z.number().describe('The amount spent for this transaction, in USD.'),
|
|
52
|
+
maxSpendingLimitInUsd: zod_1.z.number().describe("The user's daily spending limit in USD."),
|
|
53
|
+
});
|
|
54
|
+
exports.commitAllowResultSchema = zod_1.z.object({
|
|
55
|
+
spendTxHash: zod_1.z.string().describe('The hash of the transaction recording the amount spent.'),
|
|
56
|
+
});
|
|
57
|
+
exports.commitDenyResultSchema = zod_1.z.object({
|
|
58
|
+
error: zod_1.z.string().describe('A string containing the error message if the commit failed.'),
|
|
59
|
+
});
|
|
60
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/lib/schemas.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAEX,QAAA,gBAAgB,GAAG,OAAC,CAAC,MAAM,CAAC;IACvC,SAAS,EAAE,OAAC;SACT,MAAM,EAAE;SACR,QAAQ,CACP,0FAA0F,CAC3F;IACH,gBAAgB,EAAE,OAAC;SAChB,MAAM,EAAE;SACR,QAAQ,CACP,yHAAyH,CAC1H;IACH,iBAAiB,EAAE,OAAC;SACjB,MAAM,EAAE;SACR,QAAQ,CAAC,yEAAyE,CAAC;IACtF,YAAY,EAAE,OAAC;SACZ,MAAM,EAAE;SACR,QAAQ,CACP,6GAA6G,CAC9G;IACH,aAAa,EAAE,OAAC;SACb,MAAM,EAAE;SACR,QAAQ,CAAC,sEAAsE,CAAC;IACnF,SAAS,EAAE,OAAC;SACT,MAAM,EAAE;SACR,QAAQ,CAAC,sEAAsE,CAAC;CACpF,CAAC,CAAC;AAEU,QAAA,gBAAgB,GAAG,OAAC,CAAC,MAAM,CAAC;IACvC,+BAA+B,EAAE,OAAC;SAC/B,MAAM,EAAE;SACR,QAAQ,CAAC,6DAA6D,CAAC;CAC3E,CAAC,CAAC;AAEU,QAAA,yBAAyB,GAAG,OAAC,CAAC,MAAM,CAAC;IAChD,qBAAqB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;IACrF,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;CACpF,CAAC,CAAC;AAEU,QAAA,wBAAwB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/C,MAAM,EAAE,OAAC;SACN,OAAO,CAAC,0CAA0C,CAAC;SACnD,QAAQ,CAAC,sCAAsC,CAAC;IACnD,qBAAqB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;IACrF,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;CACpF,CAAC,CAAC;AAEU,QAAA,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5C,qBAAqB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;IACrF,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;CACpF,CAAC,CAAC;AAEU,QAAA,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC3C,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;IACrE,qBAAqB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;IAChG,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;CAC/F,CAAC,CAAC;AAEU,QAAA,kBAAkB,GAAG,OAAC,CAAC,MAAM,CAAC;IACzC,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;IACrF,qBAAqB,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;CACtF,CAAC,CAAC;AAEU,QAAA,uBAAuB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC9C,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yDAAyD,CAAC;CAC5F,CAAC,CAAC;AAEU,QAAA,sBAAsB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC7C,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6DAA6D,CAAC;CAC1F,CAAC,CAAC"}
|