@parallel-protocol/cli 0.2.2 → 0.2.4

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 (2) hide show
  1. package/dist/index.js +72 -46
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import { fileURLToPath } from 'url';
7
7
  import { config } from 'dotenv';
8
8
  import { hyperEvm, hemi, katana, plasma, plume, worldchain, fraxtal, xLayer, linea, mantle, sonic, tac, ink, unichain, berachain, sei, gnosis, scroll, bsc, avalanche, polygon, optimism, arbitrum, base, mainnet } from 'viem/chains';
9
9
  import { z } from 'zod';
10
- import { keccak256, toHex, isAddress, parseUnits, isHex, formatUnits, encodeFunctionData, formatEther, createPublicClient, http, createWalletClient, maxUint256, getContract, encodeAbiParameters, concat, hashTypedData, custom } from 'viem';
10
+ import { keccak256, toHex, isAddress, parseUnits, isHex, formatUnits, encodeFunctionData, formatEther, createPublicClient, http, createWalletClient, maxUint256, getContract, encodeAbiParameters, concat, hashTypedData, BaseError, ContractFunctionRevertedError, ContractFunctionZeroDataError, custom } from 'viem';
11
11
  import { createEnv } from '@t3-oss/env-core';
12
12
  import chalk5 from 'chalk';
13
13
  import { homedir } from 'os';
@@ -8068,6 +8068,15 @@ var PREVIEW_WITHDRAW_ABI = [
8068
8068
  outputs: [{ type: "uint256" }]
8069
8069
  }
8070
8070
  ];
8071
+ var PREVIEW_MINT_ABI = [
8072
+ {
8073
+ name: "previewMint",
8074
+ type: "function",
8075
+ stateMutability: "view",
8076
+ inputs: [{ type: "uint256", name: "shares" }],
8077
+ outputs: [{ type: "uint256" }]
8078
+ }
8079
+ ];
8071
8080
  function buildTiming() {
8072
8081
  const now = BigInt(Math.floor(Date.now() / 1e3));
8073
8082
  return { validAfter: now - 60n, validBefore: now + 300n };
@@ -8075,8 +8084,21 @@ function buildTiming() {
8075
8084
  function slippageUp(amount) {
8076
8085
  return amount + amount * SLIPPAGE_BPS / 10000n;
8077
8086
  }
8078
- function slippageDown(amount) {
8079
- return amount - amount * SLIPPAGE_BPS / 10000n;
8087
+ async function previewMintAssets(chain, susdp, shares) {
8088
+ return await getClient(chain).readContract({
8089
+ address: susdp,
8090
+ abi: PREVIEW_MINT_ABI,
8091
+ functionName: "previewMint",
8092
+ args: [shares]
8093
+ });
8094
+ }
8095
+ async function previewWithdrawShares(chain, susdp, assets) {
8096
+ return await getClient(chain).readContract({
8097
+ address: susdp,
8098
+ abi: PREVIEW_WITHDRAW_ABI,
8099
+ functionName: "previewWithdraw",
8100
+ args: [assets]
8101
+ });
8080
8102
  }
8081
8103
  async function readTokenDomain(chain, token) {
8082
8104
  return readTokenDomainFull(chain, token);
@@ -8216,15 +8238,6 @@ async function quoteSwapOut(chain, amountOut, tokenIn, tokenOut) {
8216
8238
  args: [amountOut, tokenIn, tokenOut]
8217
8239
  });
8218
8240
  }
8219
- async function quoteSwapIn(chain, amountIn, tokenIn, tokenOut) {
8220
- const parallelizer = getParallelizerAddress(chain);
8221
- return await getClient(chain).readContract({
8222
- address: parallelizer,
8223
- abi: PARALLELIZER_ABI,
8224
- functionName: "quoteIn",
8225
- args: [amountIn, tokenIn, tokenOut]
8226
- });
8227
- }
8228
8241
  async function prepareRouteA(chain, senderAddress, amount, recipient) {
8229
8242
  const usdpAddress = getUSDpAddress(chain);
8230
8243
  if (!usdpAddress) throw new Error(`USDp not deployed on ${chain}`);
@@ -8297,9 +8310,18 @@ async function prepareRouteB(chain, senderAddress, amount, recipient, targetToke
8297
8310
  usdpAddress,
8298
8311
  targetToken
8299
8312
  );
8300
- } catch {
8313
+ } catch (err) {
8314
+ const reverted = err instanceof BaseError && err.walk(
8315
+ (e) => e instanceof ContractFunctionRevertedError || e instanceof ContractFunctionZeroDataError
8316
+ ) !== null;
8317
+ if (reverted) {
8318
+ throw new Error(
8319
+ `${targetToken} is not a registered backing collateral on ${chain}. Use get_supported_collaterals to find valid token addresses.`
8320
+ );
8321
+ }
8322
+ const cause = err instanceof Error ? err.message.split("\n")[0] : String(err);
8301
8323
  throw new Error(
8302
- `${targetToken} is not a registered backing collateral on ${chain}. Use get_supported_collaterals to find valid token addresses.`
8324
+ `Could not quote ${targetToken} on ${chain} \u2014 transient RPC failure, retry. (${cause})`
8303
8325
  );
8304
8326
  }
8305
8327
  const amountInMax = slippageUp(amountInWei);
@@ -8375,13 +8397,15 @@ async function prepareRouteC(chain, senderAddress, amount, recipient) {
8375
8397
  const susdpAddress = getSUSDpAddress(chain);
8376
8398
  if (!usdpAddress) throw new Error(`USDp not deployed on ${chain}`);
8377
8399
  if (!susdpAddress) throw new Error(`sUSDp not deployed on ${chain}`);
8378
- const amountWei = parseUnits(amount, 18);
8400
+ const sharesWei = parseUnits(amount, 18);
8379
8401
  const { validAfter, validBefore } = buildTiming();
8380
8402
  const sharedNonce = generateNonce();
8381
- const [susdpDomain, usdpDomain] = await Promise.all([
8403
+ const [assetsNeeded, susdpDomain, usdpDomain] = await Promise.all([
8404
+ previewMintAssets(chain, susdpAddress, sharesWei),
8382
8405
  readTokenDomain(chain, susdpAddress),
8383
8406
  readTokenDomain(chain, usdpAddress)
8384
8407
  ]);
8408
+ const amountWei = slippageUp(assetsNeeded);
8385
8409
  const depositTd = buildDepositTypedData(susdpDomain, {
8386
8410
  vault: susdpAddress,
8387
8411
  owner: senderAddress,
@@ -8410,7 +8434,9 @@ async function prepareRouteC(chain, senderAddress, amount, recipient) {
8410
8434
  route: "C",
8411
8435
  steps: [
8412
8436
  {
8413
- label: "depositSignature",
8437
+ // Steps are keyed by label: "signature" is the payload's required
8438
+ // signature ("depositSignature" is Route G's extra deposit sig).
8439
+ label: "signature",
8414
8440
  description: "DepositWithAuthorization on sUSDp domain",
8415
8441
  messageHash: sig1MessageHash,
8416
8442
  typedData: depositTd
@@ -8589,14 +8615,19 @@ async function prepareRouteG(chain, senderAddress, amount, recipient) {
8589
8615
  if (!usdcAddress) throw new Error(`USDC not configured on ${chain}`);
8590
8616
  if (!susdpAddress) throw new Error(`sUSDp not deployed on ${chain}`);
8591
8617
  const parallelizer = getParallelizerAddress(chain);
8592
- const amountInWei = parseUnits(amount, 6);
8593
- const expectedUSDpOut = await quoteSwapIn(
8594
- chain,
8595
- amountInWei,
8596
- usdcAddress,
8597
- usdpAddress
8618
+ const sharesWei = parseUnits(amount, 18);
8619
+ const domainsPromise = Promise.all([
8620
+ readTokenDomain(chain, usdcAddress),
8621
+ readTokenDomain(chain, susdpAddress),
8622
+ readTokenDomain(chain, usdpAddress)
8623
+ ]);
8624
+ domainsPromise.catch(() => {
8625
+ });
8626
+ const usdpNeeded = await previewMintAssets(chain, susdpAddress, sharesWei);
8627
+ const amountOutMin = slippageUp(usdpNeeded);
8628
+ const amountInWei = slippageUp(
8629
+ await quoteSwapOut(chain, amountOutMin, usdcAddress, usdpAddress)
8598
8630
  );
8599
- const amountOutMin = slippageDown(expectedUSDpOut);
8600
8631
  const { validAfter, validBefore } = buildTiming();
8601
8632
  const swapUserSalt = generateNonce();
8602
8633
  const depositNonce = generateNonce();
@@ -8611,11 +8642,7 @@ async function prepareRouteG(chain, senderAddress, amount, recipient) {
8611
8642
  // swap recipient = payer, not merchant
8612
8643
  validBefore
8613
8644
  );
8614
- const [usdcDomain, susdpDomain, usdpDomain] = await Promise.all([
8615
- readTokenDomain(chain, usdcAddress),
8616
- readTokenDomain(chain, susdpAddress),
8617
- readTokenDomain(chain, usdpAddress)
8618
- ]);
8645
+ const [usdcDomain, susdpDomain, usdpDomain] = await domainsPromise;
8619
8646
  const swapTd = buildReceiveAuthorizationTypedData(usdcDomain, {
8620
8647
  from: senderAddress,
8621
8648
  to: parallelizer,
@@ -8704,8 +8731,8 @@ async function prepareRouteG(chain, senderAddress, amount, recipient) {
8704
8731
  }
8705
8732
  },
8706
8733
  quote: {
8707
- amountIn: amount,
8708
- amountOut: formatUnits(expectedUSDpOut, 18),
8734
+ amountIn: formatUnits(amountInWei, 6),
8735
+ amountOut: amount,
8709
8736
  slippageBps: Number(SLIPPAGE_BPS)
8710
8737
  },
8711
8738
  gasEstimate: 2e5
@@ -8714,10 +8741,13 @@ async function prepareRouteG(chain, senderAddress, amount, recipient) {
8714
8741
  async function prepareRouteH(chain, senderAddress, amount, recipient) {
8715
8742
  const susdpAddress = getSUSDpAddress(chain);
8716
8743
  if (!susdpAddress) throw new Error(`sUSDp not deployed on ${chain}`);
8717
- const sharesWei = parseUnits(amount, 18);
8744
+ const assetsWei = parseUnits(amount, 18);
8718
8745
  const { validAfter, validBefore } = buildTiming();
8719
8746
  const nonce = generateNonce();
8720
- const susdpDomain = await readTokenDomain(chain, susdpAddress);
8747
+ const [sharesWei, susdpDomain] = await Promise.all([
8748
+ previewWithdrawShares(chain, susdpAddress, assetsWei),
8749
+ readTokenDomain(chain, susdpAddress)
8750
+ ]);
8721
8751
  const redeemTd = buildRedeemTypedData(susdpDomain, {
8722
8752
  vault: susdpAddress,
8723
8753
  owner: senderAddress,
@@ -9182,10 +9212,12 @@ async function preparePayment(params) {
9182
9212
  const { chain, amount } = params;
9183
9213
  const sender = params.senderAddress;
9184
9214
  const recv = params.recipient;
9185
- const target = params.targetToken;
9186
9215
  const tokenIn = params.tokenIn ?? "usdp";
9216
+ const usdpAddress = getUSDpAddress(chain);
9217
+ const target = params.targetToken ?? usdpAddress;
9218
+ const wantsUSDp = !target || !!usdpAddress && target.toLowerCase() === usdpAddress.toLowerCase();
9187
9219
  if (tokenIn === "usdp") {
9188
- if (!target) return prepareRouteA(chain, sender, amount, recv);
9220
+ if (!target || wantsUSDp) return prepareRouteA(chain, sender, amount, recv);
9189
9221
  const susdpAddress = getSUSDpAddress(chain);
9190
9222
  if (susdpAddress && target.toLowerCase() === susdpAddress.toLowerCase()) {
9191
9223
  return prepareRouteC(chain, sender, amount, recv);
@@ -9199,13 +9231,10 @@ async function preparePayment(params) {
9199
9231
  if (tokenIn === "usdc") {
9200
9232
  const usdcAddress = getUSDCAddress(chain);
9201
9233
  if (!usdcAddress) throw new Error(`USDC not configured on ${chain}`);
9202
- if (!target || target.toLowerCase() === usdcAddress.toLowerCase()) {
9234
+ if (!target || wantsUSDp) return prepareRouteE(chain, sender, amount, recv);
9235
+ if (target.toLowerCase() === usdcAddress.toLowerCase()) {
9203
9236
  return prepareRouteF(chain, sender, amount, recv);
9204
9237
  }
9205
- const usdpAddress = getUSDpAddress(chain);
9206
- if (usdpAddress && target.toLowerCase() === usdpAddress.toLowerCase()) {
9207
- return prepareRouteE(chain, sender, amount, recv);
9208
- }
9209
9238
  const susdpAddress = getSUSDpAddress(chain);
9210
9239
  if (susdpAddress && target.toLowerCase() === susdpAddress.toLowerCase()) {
9211
9240
  return prepareRouteG(chain, sender, amount, recv);
@@ -9217,13 +9246,10 @@ async function preparePayment(params) {
9217
9246
  if (tokenIn === "susdp") {
9218
9247
  const susdpAddress = getSUSDpAddress(chain);
9219
9248
  if (!susdpAddress) throw new Error(`sUSDp not deployed on ${chain}`);
9220
- if (!target || target.toLowerCase() === susdpAddress.toLowerCase()) {
9249
+ if (!target || wantsUSDp) return prepareRouteH(chain, sender, amount, recv);
9250
+ if (target.toLowerCase() === susdpAddress.toLowerCase()) {
9221
9251
  return prepareRouteJ(chain, sender, amount, recv);
9222
9252
  }
9223
- const usdpAddress = getUSDpAddress(chain);
9224
- if (usdpAddress && target.toLowerCase() === usdpAddress.toLowerCase()) {
9225
- return prepareRouteH(chain, sender, amount, recv);
9226
- }
9227
9253
  const usdcAddressForI = getUSDCAddress(chain);
9228
9254
  if (usdcAddressForI && target.toLowerCase() === usdcAddressForI.toLowerCase()) {
9229
9255
  return prepareRouteI(chain, sender, amount, recv, target);
@@ -14561,7 +14587,7 @@ var package_default = {
14561
14587
 
14562
14588
  // package.json
14563
14589
  var package_default2 = {
14564
- version: "0.2.2"};
14590
+ version: "0.2.4"};
14565
14591
 
14566
14592
  // src/commands/version.ts
14567
14593
  function versionCommand() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parallel-protocol/cli",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "files": [