@sun-protocol/sun-sdk-protocols 0.1.0-beta.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 (60) hide show
  1. package/README.md +30 -0
  2. package/dist/chunk-5XDX5563.js +99 -0
  3. package/dist/chunk-5XDX5563.js.map +1 -0
  4. package/dist/chunk-C2YCVBPI.js +212 -0
  5. package/dist/chunk-C2YCVBPI.js.map +1 -0
  6. package/dist/chunk-ECCGOXNA.js +1317 -0
  7. package/dist/chunk-ECCGOXNA.js.map +1 -0
  8. package/dist/chunk-HD2S3Q7L.js +746 -0
  9. package/dist/chunk-HD2S3Q7L.js.map +1 -0
  10. package/dist/chunk-L5TZCDPH.js +561 -0
  11. package/dist/chunk-L5TZCDPH.js.map +1 -0
  12. package/dist/chunk-OM4OW4KB.js +224 -0
  13. package/dist/chunk-OM4OW4KB.js.map +1 -0
  14. package/dist/chunk-PEGREDLT.js +935 -0
  15. package/dist/chunk-PEGREDLT.js.map +1 -0
  16. package/dist/chunk-TSHXXRH2.js +103 -0
  17. package/dist/chunk-TSHXXRH2.js.map +1 -0
  18. package/dist/chunk-VFVKMC4H.js +521 -0
  19. package/dist/chunk-VFVKMC4H.js.map +1 -0
  20. package/dist/chunk-YMGZDXI4.js +1209 -0
  21. package/dist/chunk-YMGZDXI4.js.map +1 -0
  22. package/dist/common-8VQQ0FSU.d.cts +146 -0
  23. package/dist/common-8VQQ0FSU.d.ts +146 -0
  24. package/dist/execute-BNKh6dT6.d.cts +187 -0
  25. package/dist/execute-CVhcKZxF.d.ts +187 -0
  26. package/dist/index.cjs +5619 -0
  27. package/dist/index.cjs.map +1 -0
  28. package/dist/index.d.cts +139 -0
  29. package/dist/index.d.ts +139 -0
  30. package/dist/index.js +200 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/intents-BSXq1HvW.d.cts +200 -0
  33. package/dist/intents-CwOttD75.d.ts +200 -0
  34. package/dist/liquidity/index.cjs +2441 -0
  35. package/dist/liquidity/index.cjs.map +1 -0
  36. package/dist/liquidity/index.d.cts +83 -0
  37. package/dist/liquidity/index.d.ts +83 -0
  38. package/dist/liquidity/index.js +32 -0
  39. package/dist/liquidity/index.js.map +1 -0
  40. package/dist/positions/index.cjs +1544 -0
  41. package/dist/positions/index.cjs.map +1 -0
  42. package/dist/positions/index.d.cts +159 -0
  43. package/dist/positions/index.d.ts +159 -0
  44. package/dist/positions/index.js +25 -0
  45. package/dist/positions/index.js.map +1 -0
  46. package/dist/pump/index.cjs +1178 -0
  47. package/dist/pump/index.cjs.map +1 -0
  48. package/dist/pump/index.d.cts +16 -0
  49. package/dist/pump/index.d.ts +16 -0
  50. package/dist/pump/index.js +29 -0
  51. package/dist/pump/index.js.map +1 -0
  52. package/dist/swap/index.cjs +2259 -0
  53. package/dist/swap/index.cjs.map +1 -0
  54. package/dist/swap/index.d.cts +33 -0
  55. package/dist/swap/index.d.ts +33 -0
  56. package/dist/swap/index.js +61 -0
  57. package/dist/swap/index.js.map +1 -0
  58. package/dist/types-BTPdCC7k.d.cts +160 -0
  59. package/dist/types-BfrouFmO.d.ts +160 -0
  60. package/package.json +94 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/liquidity/intents.ts","../src/liquidity/v3.ts","../src/internal/method-parameters.ts"],"sourcesContent":["import type { TransactionIntentScope } from '@sun-protocol/sun-sdk-core'\n\nexport const SUNSWAP_V2_LIQUIDITY_PROTOCOL_ID = 'sunswap-v2'\nexport const SUNSWAP_V3_LIQUIDITY_PROTOCOL_ID = 'sunswap-v3'\nexport const SUNSWAP_V4_LIQUIDITY_PROTOCOL_ID = 'sunswap-v4'\n\nexport function liquidityIntentScope(\n protocol: string,\n operation: string,\n): TransactionIntentScope<'liquidity'> {\n return { domain: 'liquidity', protocol, operation }\n}\n","import {\n SDKError,\n assertTronAddress,\n type BigintIsh,\n type ContractCallAction,\n type Token,\n type TronAddress,\n} from '@sun-protocol/sun-sdk-core'\nimport {\n buildV3PoolStateReads,\n buildV3PositionRead,\n computeV3PoolAddress,\n Multicall,\n nearestUsableTick,\n NonfungiblePositionManager,\n Pool,\n Position,\n TickMath,\n type FeeAmount,\n} from '@sun-protocol/sun-sdk-sunswap-v3'\nimport { planApproval } from '../approval/plan.js'\nimport {\n nextPlanId,\n normalizeBaseUnitAmount,\n normalizeDeadline,\n normalizeRecipient,\n parseSlippage,\n slippageToBips,\n} from '../common.js'\nimport {\n createContextExecutor,\n requireWalletAddress,\n resolveProtocolContract,\n type ProtocolsContext,\n} from '../context.js'\nimport { executeTransactionPlan } from '../execute-plan.js'\nimport { methodParametersToAction } from '../internal/method-parameters.js'\nimport { attachApprovalIntent } from '../internal/intents.js'\nimport {\n readMulticallRequired,\n readRequiredContract,\n} from '../internal/reads.js'\nimport {\n evmHexToTronAddress,\n normalizeProtocolToken,\n tronAddressToEvmAddress,\n type ProtocolToken,\n} from '../internal/tokens.js'\nimport type {\n TransactionPlan,\n TransactionPlanExecutionResult,\n} from '../types/plan.js'\nimport type {\n V3AddLiquidityInput,\n V3IncreaseLiquidityInput,\n V3PoolStateInput,\n} from './types.js'\nimport {\n liquidityIntentScope,\n SUNSWAP_V3_LIQUIDITY_PROTOCOL_ID,\n} from './intents.js'\n\nexport interface V3PoolLookupInput {\n readonly tokenA: string\n readonly tokenB: string\n readonly fee: number\n readonly contracts?: V3AddLiquidityInput['contracts']\n}\n\nexport interface V3PositionContext {\n readonly tokenA: TronAddress\n readonly tokenB: TronAddress\n readonly fee: number\n readonly tickLower: number\n readonly tickUpper: number\n}\n\ninterface V3Slot0ObjectResult {\n readonly sqrtPriceX96?: unknown\n readonly sqrtRatioX96?: unknown\n readonly tick?: unknown\n}\n\ninterface V3PositionObjectResult {\n readonly token0?: unknown\n readonly token1?: unknown\n readonly fee?: unknown\n readonly tickLower?: unknown\n readonly tickUpper?: unknown\n}\n\nfunction integerString(value: unknown, label: string): string {\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'bigint') {\n return BigInt(value.toString()).toString()\n }\n throw new SDKError('SDK_CONTRACT_ERROR', `${label} must be an integer-like contract result`, { value })\n}\n\nfunction integerNumber(value: unknown, label: string): number {\n const parsed = Number(integerString(value, label))\n if (!Number.isSafeInteger(parsed)) {\n throw new SDKError('SDK_CONTRACT_ERROR', `${label} must be a safe integer`, { value })\n }\n return parsed\n}\n\nfunction positionToken(value: unknown, label: string): TronAddress {\n if (typeof value !== 'string') {\n throw new SDKError('SDK_CONTRACT_ERROR', `${label} must be an address string`, { value })\n }\n if (value.startsWith('0x')) return evmHexToTronAddress(value, label)\n if (/^41[0-9a-fA-F]{40}$/.test(value)) {\n return evmHexToTronAddress(`0x${value.slice(2)}`, label)\n }\n return assertTronAddress(value, label)\n}\n\nfunction parseV3Slot0(result: unknown): { sqrtRatioX96: string; tickCurrent: number } {\n if (Array.isArray(result)) {\n return {\n sqrtRatioX96: integerString(result[0], 'sqrtRatioX96'),\n tickCurrent: integerNumber(result[1], 'tickCurrent'),\n }\n }\n if (typeof result === 'object' && result !== null) {\n const slot0 = result as V3Slot0ObjectResult\n return {\n sqrtRatioX96: integerString(slot0.sqrtPriceX96 ?? slot0.sqrtRatioX96, 'sqrtRatioX96'),\n tickCurrent: integerNumber(slot0.tick, 'tickCurrent'),\n }\n }\n throw new SDKError('SDK_CONTRACT_ERROR', 'V3 slot0 result is malformed', { result })\n}\n\nexport async function resolveV3PoolState(\n context: ProtocolsContext,\n input: V3PoolLookupInput,\n): Promise<V3PoolStateInput> {\n const tokenA = normalizeProtocolToken(context, input.tokenA, 'tokenA')\n const tokenB = normalizeProtocolToken(context, input.tokenB, 'tokenB')\n const poolAddress = computeV3PoolAddress({\n network: context.network,\n tokenA: tokenA.contractAddress,\n tokenB: tokenB.contractAddress,\n fee: input.fee,\n factory: resolveProtocolContract(context, input.contracts, 'sunswapV3Factory'),\n })\n const [slot0Result, liquidityResult, feeResult, tickSpacingResult] = await readMulticallRequired<unknown>(\n context,\n buildV3PoolStateReads({ pool: poolAddress }),\n 'V3 pool state read',\n )\n const fee = integerNumber(feeResult, 'fee')\n if (fee !== input.fee) {\n throw new SDKError('SDK_CONTRACT_ERROR', 'V3 pool fee does not match requested fee', {\n pool: poolAddress,\n requestedFee: input.fee,\n poolFee: fee,\n })\n }\n const slot0 = parseV3Slot0(slot0Result)\n return {\n sqrtRatioX96: slot0.sqrtRatioX96,\n liquidity: integerString(liquidityResult, 'liquidity'),\n tickCurrent: slot0.tickCurrent,\n tickSpacing: integerNumber(tickSpacingResult, 'tickSpacing'),\n }\n}\n\nexport async function resolveV3PositionContext(\n context: ProtocolsContext,\n tokenId: BigintIsh,\n contracts?: V3IncreaseLiquidityInput['contracts'],\n): Promise<V3PositionContext> {\n const result = await readRequiredContract<unknown>(\n context,\n buildV3PositionRead({\n network: context.network,\n tokenId,\n positionManager: resolveProtocolContract(context, contracts, 'sunswapV3PositionManager'),\n }),\n 'V3 position context read',\n )\n let token0: unknown\n let token1: unknown\n let fee: unknown\n let tickLower: unknown\n let tickUpper: unknown\n if (Array.isArray(result)) {\n token0 = result[2]\n token1 = result[3]\n fee = result[4]\n tickLower = result[5]\n tickUpper = result[6]\n } else if (typeof result === 'object' && result !== null) {\n const position = result as V3PositionObjectResult\n token0 = position.token0\n token1 = position.token1\n fee = position.fee\n tickLower = position.tickLower\n tickUpper = position.tickUpper\n } else {\n throw new SDKError('SDK_CONTRACT_ERROR', 'V3 position result is malformed', { result })\n }\n return {\n tokenA: positionToken(token0, 'token0'),\n tokenB: positionToken(token1, 'token1'),\n fee: integerNumber(fee, 'fee'),\n tickLower: integerNumber(tickLower, 'tickLower'),\n tickUpper: integerNumber(tickUpper, 'tickUpper'),\n }\n}\n\nexport function normalizeSingleSideAmounts(input: {\n readonly amount0?: BigintIsh\n readonly amount1?: BigintIsh\n}): { amount0: BigintIsh; amount1: BigintIsh } {\n if (input.amount0 === undefined && input.amount1 === undefined) {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'V3 liquidity requires at least one of amount0 or amount1')\n }\n return {\n amount0: input.amount0 ?? '0',\n amount1: input.amount1 ?? '0',\n }\n}\n\nfunction assertV3PositionContextMatches(\n context: ProtocolsContext,\n tokenId: string,\n input: V3IncreaseLiquidityInput,\n position: V3PositionContext,\n): void {\n const mismatches: Record<string, { readonly supplied: unknown; readonly position: unknown }> = {}\n const suppliedTokenA = input.tokenA === undefined\n ? undefined\n : normalizeV3ContextToken(context, input.tokenA, 'tokenA')\n const suppliedTokenB = input.tokenB === undefined\n ? undefined\n : normalizeV3ContextToken(context, input.tokenB, 'tokenB')\n const positionTokens = [position.tokenA, position.tokenB] as const\n if (suppliedTokenA !== undefined && suppliedTokenB !== undefined) {\n const pairMatches = (suppliedTokenA === position.tokenA && suppliedTokenB === position.tokenB)\n || (suppliedTokenA === position.tokenB && suppliedTokenB === position.tokenA)\n if (!pairMatches) {\n mismatches.tokens = { supplied: [suppliedTokenA, suppliedTokenB], position: positionTokens }\n }\n } else {\n if (suppliedTokenA !== undefined && !positionTokens.includes(suppliedTokenA)) {\n mismatches.tokenA = { supplied: suppliedTokenA, position: positionTokens }\n }\n if (suppliedTokenB !== undefined && !positionTokens.includes(suppliedTokenB)) {\n mismatches.tokenB = { supplied: suppliedTokenB, position: positionTokens }\n }\n }\n if (input.fee !== undefined && input.fee !== position.fee) {\n mismatches.fee = { supplied: input.fee, position: position.fee }\n }\n if (input.tickLower !== undefined && input.tickLower !== position.tickLower) {\n mismatches.tickLower = { supplied: input.tickLower, position: position.tickLower }\n }\n if (input.tickUpper !== undefined && input.tickUpper !== position.tickUpper) {\n mismatches.tickUpper = { supplied: input.tickUpper, position: position.tickUpper }\n }\n if (Object.keys(mismatches).length > 0) {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'V3 increase context does not match the tokenId position', {\n tokenId,\n mismatches,\n })\n }\n}\n\nfunction normalizeV3ContextToken(context: ProtocolsContext, token: string, label: string): TronAddress {\n const normalized = normalizeProtocolToken(context, token, label)\n return normalized.kind === 'native' ? normalized.wrappedContractAddress : normalized.contractAddress\n}\n\nfunction resolveTickRange(input: {\n readonly tickLower?: number\n readonly tickUpper?: number\n readonly tickRangeWidth?: number\n readonly pool: V3PoolStateInput\n}): { tickLower: number; tickUpper: number; derived: boolean } {\n if (input.tickLower !== undefined && input.tickUpper !== undefined) {\n return { tickLower: input.tickLower, tickUpper: input.tickUpper, derived: false }\n }\n if (input.tickLower !== undefined || input.tickUpper !== undefined) {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'tickLower and tickUpper must be provided together')\n }\n if (!Number.isInteger(input.tickRangeWidth) || (input.tickRangeWidth ?? 0) <= 0) {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'tickRangeWidth must be a positive integer when ticks are omitted', {\n tickRangeWidth: input.tickRangeWidth,\n })\n }\n const tickSpacing = input.pool.tickSpacing\n if (tickSpacing === undefined) {\n throw new SDKError('SDK_INVALID_ARGUMENT', 'pool tickSpacing is required to derive a tick range')\n }\n const width = input.tickRangeWidth as number\n const lowerTarget = Math.max(TickMath.MIN_TICK, input.pool.tickCurrent - width * tickSpacing)\n const upperTarget = Math.min(TickMath.MAX_TICK, input.pool.tickCurrent + width * tickSpacing)\n let tickLower = nearestUsableTick(lowerTarget, tickSpacing)\n let tickUpper = nearestUsableTick(upperTarget, tickSpacing)\n if (tickUpper - tickLower < tickSpacing) {\n const maxUsableTick = nearestUsableTick(TickMath.MAX_TICK, tickSpacing)\n if (tickUpper < maxUsableTick) tickUpper += tickSpacing\n else tickLower -= tickSpacing\n }\n return {\n tickLower,\n tickUpper,\n derived: true,\n }\n}\n\nfunction createPool(input: {\n readonly context: ProtocolsContext\n readonly tokenA: string\n readonly tokenB: string\n readonly fee: number\n readonly pool: V3PoolStateInput\n}): { pool: Pool; tokenA: ProtocolToken; tokenB: ProtocolToken } {\n const tokenA = normalizeProtocolToken(input.context, input.tokenA, 'tokenA')\n const tokenB = normalizeProtocolToken(input.context, input.tokenB, 'tokenB')\n return {\n tokenA,\n tokenB,\n pool: new Pool({\n tokenA: tokenA.token,\n tokenB: tokenB.token,\n fee: input.fee as FeeAmount,\n sqrtRatioX96: normalizeBaseUnitAmount(input.pool.sqrtRatioX96, 'sqrtRatioX96'),\n liquidity: normalizeBaseUnitAmount(input.pool.liquidity, 'pool liquidity', { allowZero: true }),\n tickCurrent: input.pool.tickCurrent,\n ...(input.pool.tickSpacing !== undefined ? { tickSpacing: input.pool.tickSpacing } : {}),\n }),\n }\n}\n\nfunction createPosition(input: {\n readonly pool: Pool\n readonly tickLower: number\n readonly tickUpper: number\n readonly amount0: string\n readonly amount1: string\n readonly useFullPrecision?: boolean\n}): Position {\n return Position.fromAmounts({\n pool: input.pool,\n tickLower: input.tickLower,\n tickUpper: input.tickUpper,\n amount0: input.amount0,\n amount1: input.amount1,\n useFullPrecision: input.useFullPrecision ?? true,\n })\n}\n\nfunction isNativePoolToken(poolToken: Token, tokenA: ProtocolToken, tokenB: ProtocolToken): boolean {\n return (tokenA.kind === 'native' && poolToken.equals(tokenA.token)) || (tokenB.kind === 'native' && poolToken.equals(tokenB.token))\n}\n\nasync function planTokenApproval(input: {\n readonly context: ProtocolsContext\n readonly owner: TronAddress\n readonly token: Token\n readonly amount: string\n readonly spender: TronAddress\n readonly approval: V3AddLiquidityInput['approval']\n readonly tokenA: ProtocolToken\n readonly tokenB: ProtocolToken\n readonly operation: 'add-liquidity' | 'increase-liquidity'\n}): Promise<readonly ContractCallAction[]> {\n if (isNativePoolToken(input.token, input.tokenA, input.tokenB)) return []\n if (BigInt(input.amount) === 0n) return []\n const approval = await planApproval(\n input.context,\n {\n asset: { type: 'token', token: evmHexToTronAddress(input.token.address) },\n owner: input.owner,\n spender: input.spender,\n amount: input.amount,\n },\n { mode: input.approval ?? 'auto' },\n )\n return attachApprovalIntent(\n approval.actions,\n liquidityIntentScope(SUNSWAP_V3_LIQUIDITY_PROTOCOL_ID, input.operation),\n input.token.symbol ?? input.token.address,\n ) as readonly ContractCallAction[]\n}\n\nfunction amountForToken(position: Position, token: Token): string {\n if (position.pool.token0.equals(token)) return position.mintAmounts.amount0.toString()\n return position.mintAmounts.amount1.toString()\n}\n\nfunction applyExplicitAddMinimums(\n methodParameters: ReturnType<typeof NonfungiblePositionManager.addCallParameters>,\n amount0Min: string,\n amount1Min: string,\n): ReturnType<typeof NonfungiblePositionManager.addCallParameters> {\n const parameter = methodParameters.parameter[0] as {\n readonly type: 'bytes[]'\n readonly value: readonly string[]\n }\n const mintSelector = NonfungiblePositionManager.INTERFACE.getSighash('mint')\n const calldatas = parameter.value.map((calldata) => {\n if (!calldata.startsWith(mintSelector)) return calldata\n const [mint] = NonfungiblePositionManager.INTERFACE.decodeFunctionData('mint', calldata) as unknown as [{\n readonly token0: string\n readonly token1: string\n readonly fee: unknown\n readonly tickLower: unknown\n readonly tickUpper: unknown\n readonly amount0Desired: unknown\n readonly amount1Desired: unknown\n readonly recipient: string\n readonly deadline: unknown\n }]\n return NonfungiblePositionManager.INTERFACE.encodeFunctionData('mint', [{\n token0: mint.token0,\n token1: mint.token1,\n fee: mint.fee,\n tickLower: mint.tickLower,\n tickUpper: mint.tickUpper,\n amount0Desired: mint.amount0Desired,\n amount1Desired: mint.amount1Desired,\n amount0Min,\n amount1Min,\n recipient: mint.recipient,\n deadline: mint.deadline,\n }])\n })\n return {\n ...methodParameters,\n calldata: Multicall.encodeMulticall(calldatas),\n parameter: [{ type: 'bytes[]', value: calldatas }],\n }\n}\n\nexport class V3LiquidityClient {\n constructor(private readonly context: ProtocolsContext) {}\n\n readonly add = {\n plan: async (input: V3AddLiquidityInput): Promise<TransactionPlan> => this.planAdd(input),\n execute: async (input: V3AddLiquidityInput): Promise<TransactionPlanExecutionResult> =>\n executeTransactionPlan(await this.planAdd(input), createContextExecutor(this.context)),\n }\n\n readonly increase = {\n plan: async (input: V3IncreaseLiquidityInput): Promise<TransactionPlan> => this.planIncrease(input),\n execute: async (input: V3IncreaseLiquidityInput): Promise<TransactionPlanExecutionResult> =>\n executeTransactionPlan(await this.planIncrease(input), createContextExecutor(this.context)),\n }\n\n private async planAdd(input: V3AddLiquidityInput): Promise<TransactionPlan> {\n const positionManager = resolveProtocolContract(this.context, input.contracts, 'sunswapV3PositionManager')\n const planId = nextPlanId(this.context, 'liquidity-v3-add')\n const owner = await requireWalletAddress(this.context, 'V3 add liquidity')\n const recipient = await normalizeRecipient(this.context, input.recipient, 'V3 add liquidity', owner)\n const deadline = normalizeDeadline(this.context, input)\n const amounts = normalizeSingleSideAmounts(input)\n const amount0 = normalizeBaseUnitAmount(amounts.amount0, 'amount0', { allowZero: true })\n const amount1 = normalizeBaseUnitAmount(amounts.amount1, 'amount1', { allowZero: true })\n const poolDerived = input.pool === undefined\n const poolState = input.pool ?? await resolveV3PoolState(this.context, input)\n const tickRange = resolveTickRange({\n ...(input.tickLower !== undefined ? { tickLower: input.tickLower } : {}),\n ...(input.tickUpper !== undefined ? { tickUpper: input.tickUpper } : {}),\n ...(input.tickRangeWidth !== undefined ? { tickRangeWidth: input.tickRangeWidth } : {}),\n pool: poolState,\n })\n const { pool, tokenA, tokenB } = createPool({\n context: this.context,\n tokenA: input.tokenA,\n tokenB: input.tokenB,\n fee: input.fee,\n pool: poolState,\n })\n const position = createPosition({\n pool,\n tickLower: tickRange.tickLower,\n tickUpper: tickRange.tickUpper,\n amount0,\n amount1,\n ...(input.useFullPrecision !== undefined ? { useFullPrecision: input.useFullPrecision } : {}),\n })\n const slippageTolerance = parseSlippage(input.slippage ?? '0.5%')\n const slippageMinimums = position.mintAmountsWithSlippage(slippageTolerance)\n const amount0Min = input.amount0Min === undefined\n ? slippageMinimums.amount0.toString()\n : normalizeBaseUnitAmount(input.amount0Min, 'amount0Min', { allowZero: true })\n const amount1Min = input.amount1Min === undefined\n ? slippageMinimums.amount1.toString()\n : normalizeBaseUnitAmount(input.amount1Min, 'amount1Min', { allowZero: true })\n const generatedMethodParameters = NonfungiblePositionManager.addCallParameters(position, {\n recipient: tronAddressToEvmAddress(recipient, 'recipient'),\n ...(input.createPool !== undefined ? { createPool: input.createPool } : {}),\n slippageTolerance,\n deadline,\n ...(tokenA.kind === 'native' || tokenB.kind === 'native' ? { useNative: this.context.chain.nativeCurrency } : {}),\n })\n const methodParameters = input.amount0Min === undefined && input.amount1Min === undefined\n ? generatedMethodParameters\n : applyExplicitAddMinimums(generatedMethodParameters, amount0Min, amount1Min)\n const action = methodParametersToAction({\n id: `${planId}-tx`,\n target: positionManager,\n methodParameters,\n ...(input.feeLimit !== undefined ? { feeLimit: input.feeLimit } : {}),\n waitForReceipt: 'included',\n intent: {\n kind: 'add-liquidity',\n scope: liquidityIntentScope(SUNSWAP_V3_LIQUIDITY_PROTOCOL_ID, 'add-liquidity'),\n },\n })\n const approvals = [\n ...await planTokenApproval({\n context: this.context,\n owner,\n token: pool.token0,\n amount: amountForToken(position, pool.token0),\n spender: positionManager,\n approval: input.approval,\n tokenA,\n tokenB,\n operation: 'add-liquidity',\n }),\n ...await planTokenApproval({\n context: this.context,\n owner,\n token: pool.token1,\n amount: amountForToken(position, pool.token1),\n spender: positionManager,\n approval: input.approval,\n tokenA,\n tokenB,\n operation: 'add-liquidity',\n }),\n ]\n\n return {\n id: planId,\n kind: 'liquidity',\n network: this.context.network,\n owner,\n summary: { title: 'Add SunSwap V3 liquidity', lines: [`Recipient ${recipient}`] },\n approvals,\n transactions: [action],\n metadata: {\n protocol: 'sunswap-v3',\n operation: 'add-liquidity',\n recipient,\n deadline,\n slippageBips: slippageToBips(input.slippage ?? '0.5%'),\n poolDerived,\n tickRangeDerived: tickRange.derived,\n tickLower: tickRange.tickLower,\n tickUpper: tickRange.tickUpper,\n },\n }\n }\n\n private async planIncrease(input: V3IncreaseLiquidityInput): Promise<TransactionPlan> {\n const positionManager = resolveProtocolContract(this.context, input.contracts, 'sunswapV3PositionManager')\n const planId = nextPlanId(this.context, 'liquidity-v3-increase')\n const owner = await requireWalletAddress(this.context, 'V3 increase liquidity')\n const deadline = normalizeDeadline(this.context, input)\n const tokenId = normalizeBaseUnitAmount(input.tokenId, 'tokenId')\n const amounts = normalizeSingleSideAmounts(input)\n const amount0 = normalizeBaseUnitAmount(amounts.amount0, 'amount0', { allowZero: true })\n const amount1 = normalizeBaseUnitAmount(amounts.amount1, 'amount1', { allowZero: true })\n const positionDerived = input.tokenA === undefined\n || input.tokenB === undefined\n || input.fee === undefined\n || input.tickLower === undefined\n || input.tickUpper === undefined\n const positionContext = await resolveV3PositionContext(this.context, tokenId, input.contracts)\n assertV3PositionContextMatches(this.context, tokenId, input, positionContext)\n const tokenAInput = input.tokenA ?? positionContext.tokenA\n const tokenBInput = input.tokenB ?? positionContext.tokenB\n const fee = input.fee ?? positionContext.fee\n const tickLower = input.tickLower ?? positionContext.tickLower\n const tickUpper = input.tickUpper ?? positionContext.tickUpper\n if (tokenAInput === undefined || tokenBInput === undefined || fee === undefined || tickLower === undefined || tickUpper === undefined) {\n throw new SDKError('SDK_CONTRACT_ERROR', 'V3 position context is incomplete', { tokenId })\n }\n const poolDerived = input.pool === undefined\n const poolState = input.pool ?? await resolveV3PoolState(this.context, {\n tokenA: tokenAInput,\n tokenB: tokenBInput,\n fee,\n contracts: input.contracts,\n })\n const { pool, tokenA, tokenB } = createPool({\n context: this.context,\n tokenA: tokenAInput,\n tokenB: tokenBInput,\n fee,\n pool: poolState,\n })\n const position = createPosition({\n pool,\n tickLower,\n tickUpper,\n amount0,\n amount1,\n ...(input.useFullPrecision !== undefined ? { useFullPrecision: input.useFullPrecision } : {}),\n })\n const methodParameters = NonfungiblePositionManager.addCallParameters(position, {\n tokenId,\n slippageTolerance: parseSlippage(input.slippage ?? '0.5%'),\n deadline,\n ...(tokenA.kind === 'native' || tokenB.kind === 'native' ? { useNative: this.context.chain.nativeCurrency } : {}),\n })\n const action = methodParametersToAction({\n id: `${planId}-tx`,\n target: positionManager,\n methodParameters,\n ...(input.feeLimit !== undefined ? { feeLimit: input.feeLimit } : {}),\n waitForReceipt: 'included',\n intent: {\n kind: 'add-liquidity',\n scope: liquidityIntentScope(SUNSWAP_V3_LIQUIDITY_PROTOCOL_ID, 'increase-liquidity'),\n positionId: tokenId,\n },\n })\n const approvals = [\n ...await planTokenApproval({\n context: this.context,\n owner,\n token: pool.token0,\n amount: amountForToken(position, pool.token0),\n spender: positionManager,\n approval: input.approval,\n tokenA,\n tokenB,\n operation: 'increase-liquidity',\n }),\n ...await planTokenApproval({\n context: this.context,\n owner,\n token: pool.token1,\n amount: amountForToken(position, pool.token1),\n spender: positionManager,\n approval: input.approval,\n tokenA,\n tokenB,\n operation: 'increase-liquidity',\n }),\n ]\n\n return {\n id: planId,\n kind: 'liquidity',\n network: this.context.network,\n owner,\n summary: { title: 'Increase SunSwap V3 liquidity', lines: [`Position ${tokenId}`] },\n approvals,\n transactions: [action],\n metadata: {\n protocol: 'sunswap-v3',\n operation: 'increase-liquidity',\n tokenId,\n deadline,\n slippageBips: slippageToBips(input.slippage ?? '0.5%'),\n positionDerived,\n poolDerived,\n },\n }\n }\n}\n","import {\n createContractCallAction,\n type ContractCallAction,\n type ContractParameter,\n type TransactionReceiptFinality,\n type TransactionIntent,\n type TronAddress,\n} from '@sun-protocol/sun-sdk-core'\n\nexport interface ProtocolMethodParameters {\n readonly calldata: string\n readonly value: string\n readonly function_selector: string\n readonly parameter: readonly ContractParameter[] | readonly unknown[]\n}\n\nexport interface MethodParametersToActionInput {\n readonly id: string\n readonly target: TronAddress\n readonly methodParameters: ProtocolMethodParameters\n readonly feeLimit?: number\n readonly waitForReceipt?: TransactionReceiptFinality\n readonly metadata?: Record<string, unknown>\n readonly intent?: TransactionIntent\n}\n\nexport function methodParametersToAction(input: MethodParametersToActionInput): ContractCallAction {\n return createContractCallAction({\n id: input.id,\n target: input.target,\n functionSelector: input.methodParameters.function_selector,\n parameters: input.methodParameters.parameter as readonly ContractParameter[],\n callValue: BigInt(input.methodParameters.value),\n ...(input.feeLimit !== undefined ? { feeLimit: input.feeLimit } : {}),\n ...(input.waitForReceipt !== undefined ? { waitForReceipt: input.waitForReceipt } : {}),\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n ...(input.intent !== undefined ? { intent: input.intent } : {}),\n })\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,224 @@
1
+ import {
2
+ planApproval
3
+ } from "./chunk-C2YCVBPI.js";
4
+ import {
5
+ nextPlanId,
6
+ normalizeDeadline,
7
+ requireRuntime
8
+ } from "./chunk-VFVKMC4H.js";
9
+
10
+ // src/approval/permit2.ts
11
+ import {
12
+ SDKError as SDKError2,
13
+ assertTronAddress,
14
+ createTypedDataSignatureAction
15
+ } from "@sun-protocol/sun-sdk-core";
16
+
17
+ // src/internal/permit2-adapter.ts
18
+ import {
19
+ SDKError,
20
+ createContractCallAction
21
+ } from "@sun-protocol/sun-sdk-core";
22
+ import { PERMIT_TYPES, toEvmHex } from "@sun-protocol/permit2-sdk";
23
+ var PERMIT2_TYPED_DATA_CHAIN_IDS = {
24
+ mainnet: 728126428,
25
+ nile: 3448148188
26
+ };
27
+ function buildPermit2HelperRead(input) {
28
+ return {
29
+ target: input.helper,
30
+ functionSelector: "checkPermit2Allowance(address,address,address,address,uint256)",
31
+ parameters: [
32
+ { type: "address", value: input.permit2 },
33
+ { type: "address", value: input.token },
34
+ { type: "address", value: input.owner },
35
+ { type: "address", value: input.spender },
36
+ { type: "uint256", value: input.amount }
37
+ ],
38
+ outputs: [{ type: "bool", name: "approved" }]
39
+ };
40
+ }
41
+ function normalizePermit2HelperResult(result) {
42
+ if (typeof result === "boolean") return result;
43
+ if (Array.isArray(result) && result.length === 1 && typeof result[0] === "boolean") return result[0];
44
+ throw new SDKError("SDK_CONTRACT_ERROR", "Invalid Permit2Helper approval result", { result });
45
+ }
46
+ function buildPermit2AllowanceRead(input) {
47
+ return {
48
+ target: input.permit2,
49
+ functionSelector: "allowance(address,address,address)",
50
+ parameters: [
51
+ { type: "address", value: input.owner },
52
+ { type: "address", value: input.token },
53
+ { type: "address", value: input.spender }
54
+ ],
55
+ outputs: [
56
+ { type: "uint160", name: "amount" },
57
+ { type: "uint48", name: "expiration" },
58
+ { type: "uint48", name: "nonce" }
59
+ ]
60
+ };
61
+ }
62
+ function bigintFrom(value, label) {
63
+ if (typeof value === "bigint") return value;
64
+ if (typeof value === "number" && Number.isSafeInteger(value)) return BigInt(value);
65
+ if (typeof value === "string" && /^[0-9]+$/.test(value)) return BigInt(value);
66
+ throw new SDKError("SDK_CONTRACT_ERROR", `Invalid Permit2 allowance ${label}`, { value });
67
+ }
68
+ function normalizePermit2Allowance(result) {
69
+ if (Array.isArray(result)) {
70
+ return {
71
+ amount: bigintFrom(result[0], "amount"),
72
+ expiration: bigintFrom(result[1], "expiration"),
73
+ nonce: bigintFrom(result[2], "nonce")
74
+ };
75
+ }
76
+ if (typeof result === "object" && result !== null) {
77
+ const value = result;
78
+ return {
79
+ amount: bigintFrom(value.amount ?? value[0], "amount"),
80
+ expiration: bigintFrom(value.expiration ?? value[1], "expiration"),
81
+ nonce: bigintFrom(value.nonce ?? value[2], "nonce")
82
+ };
83
+ }
84
+ throw new SDKError("SDK_CONTRACT_ERROR", "Invalid Permit2 allowance result", { result });
85
+ }
86
+ function buildPermit2TypedData(input) {
87
+ return {
88
+ primaryType: "PermitSingle",
89
+ domain: {
90
+ name: "Permit2",
91
+ chainId: PERMIT2_TYPED_DATA_CHAIN_IDS[input.network],
92
+ verifyingContract: toEvmHex(input.permit2)
93
+ },
94
+ types: PERMIT_TYPES,
95
+ message: {
96
+ details: {
97
+ token: toEvmHex(input.token),
98
+ amount: input.amount,
99
+ expiration: input.expiration,
100
+ nonce: input.nonce
101
+ },
102
+ spender: toEvmHex(input.spender),
103
+ sigDeadline: input.sigDeadline
104
+ }
105
+ };
106
+ }
107
+ function buildPermit2ApproveAction(input) {
108
+ return createContractCallAction({
109
+ id: input.id,
110
+ target: input.permit2,
111
+ functionSelector: "approve(address,address,uint160,uint48)",
112
+ waitForReceipt: "included",
113
+ parameters: [
114
+ { type: "address", value: input.token },
115
+ { type: "address", value: input.spender },
116
+ { type: "uint160", value: input.amount },
117
+ { type: "uint48", value: input.expiration }
118
+ ]
119
+ });
120
+ }
121
+
122
+ // src/approval/permit2.ts
123
+ async function hasTypedDataCapability(context, capabilities) {
124
+ if (capabilities) return capabilities.signTypedData;
125
+ return (await context.runtime?.getWallet())?.capabilities.signTypedData === true;
126
+ }
127
+ function normalizePlanDeadlineValue(value) {
128
+ return typeof value === "bigint" ? value.toString() : value;
129
+ }
130
+ var MAX_UINT160 = "1461501637330902918203684832716283019655932542975";
131
+ async function planRouterPermit2Authorization(context, input) {
132
+ if (input.approval === "none") {
133
+ return { actions: [], mode: "none" };
134
+ }
135
+ const helper = context.chain.contracts.permit2Helper;
136
+ if (!helper) {
137
+ throw new SDKError2("SDK_INVALID_ARGUMENT", `Permit2Helper is not configured for ${context.network}`, {
138
+ network: context.network,
139
+ contract: "permit2Helper"
140
+ });
141
+ }
142
+ const runtime = requireRuntime(context, "Router Permit2 authorization");
143
+ const actions = [];
144
+ const token = assertTronAddress(input.token, "token");
145
+ const spender = input.spender ? assertTronAddress(input.spender, "spender") : context.chain.contracts.universalRouter;
146
+ const tokenApproval = await planApproval(context, {
147
+ asset: { type: "token", token },
148
+ owner: input.owner,
149
+ spender: context.chain.contracts.permit2,
150
+ amount: input.amount
151
+ }, {
152
+ mode: "auto",
153
+ amount: input.approveAmountType ?? "exact"
154
+ });
155
+ actions.push(...tokenApproval.actions);
156
+ const approved = normalizePermit2HelperResult(await runtime.readContract(buildPermit2HelperRead({
157
+ helper,
158
+ permit2: context.chain.contracts.permit2,
159
+ owner: input.owner,
160
+ token,
161
+ spender,
162
+ amount: input.amount
163
+ })));
164
+ const permit2Amount = input.approveAmountType === "max" ? MAX_UINT160 : input.amount;
165
+ if (approved) {
166
+ return { actions, mode: "already-approved" };
167
+ }
168
+ const expiration = normalizeDeadline(context, {
169
+ ttlSeconds: input.ttlSeconds ?? 30 * 24 * 60 * 60,
170
+ ...input.deadline !== void 0 ? { deadline: normalizePlanDeadlineValue(input.deadline) } : {}
171
+ }).toString();
172
+ const sigDeadline = normalizeDeadline(context, { ttlSeconds: 3600 }).toString();
173
+ if ((input.approval === "auto" || input.approval === "permit2") && await hasTypedDataCapability(context, input.walletCapabilities)) {
174
+ const allowance = normalizePermit2Allowance(await runtime.readContract(buildPermit2AllowanceRead({
175
+ permit2: context.chain.contracts.permit2,
176
+ owner: input.owner,
177
+ token,
178
+ spender
179
+ })));
180
+ const typedData = buildPermit2TypedData({
181
+ network: context.network,
182
+ permit2: context.chain.contracts.permit2,
183
+ owner: input.owner,
184
+ token,
185
+ spender,
186
+ amount: permit2Amount,
187
+ expiration,
188
+ sigDeadline,
189
+ nonce: allowance.nonce.toString()
190
+ });
191
+ const signatureActionId = `${nextPlanId(context, "permit2")}-signature`;
192
+ actions.push(createTypedDataSignatureAction({
193
+ id: signatureActionId,
194
+ typedData
195
+ }));
196
+ return {
197
+ actions,
198
+ signatureActionId,
199
+ permitSingle: typedData.message,
200
+ mode: "typed-data"
201
+ };
202
+ }
203
+ if (input.approval === "permit2" || input.approval === "auto" || input.approval === "approve") {
204
+ actions.push(buildPermit2ApproveAction({
205
+ id: `${nextPlanId(context, "permit2")}-approve`,
206
+ permit2: context.chain.contracts.permit2,
207
+ token,
208
+ spender,
209
+ amount: permit2Amount,
210
+ expiration
211
+ }));
212
+ return { actions, mode: "on-chain" };
213
+ }
214
+ throw new SDKError2(
215
+ "SDK_INVALID_ARGUMENT",
216
+ "Unsupported approval mode for Router Permit2 authorization",
217
+ { approval: input.approval }
218
+ );
219
+ }
220
+
221
+ export {
222
+ planRouterPermit2Authorization
223
+ };
224
+ //# sourceMappingURL=chunk-OM4OW4KB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/approval/permit2.ts","../src/internal/permit2-adapter.ts"],"sourcesContent":["import {\n SDKError,\n assertTronAddress,\n createTypedDataSignatureAction,\n type TransactionAction,\n type TronAddress,\n} from '@sun-protocol/sun-sdk-core'\nimport type { WalletCapabilities } from '@sun-protocol/sun-sdk-runtime'\nimport { nextPlanId, normalizeDeadline } from '../common.js'\nimport { requireRuntime, type ProtocolsContext } from '../context.js'\nimport {\n buildPermit2AllowanceRead,\n buildPermit2HelperRead,\n buildPermit2ApproveAction,\n buildPermit2TypedData,\n normalizePermit2Allowance,\n normalizePermit2HelperResult,\n} from '../internal/permit2-adapter.js'\nimport type { ApprovalMode } from '../types/options.js'\nimport { planApproval } from './plan.js'\n\nexport interface RouterPermit2AuthorizationInput {\n readonly owner: TronAddress\n readonly token: TronAddress\n readonly spender?: TronAddress\n readonly amount: string\n readonly approval: ApprovalMode\n readonly ttlSeconds?: number\n readonly deadline?: string | number | bigint\n readonly walletCapabilities?: WalletCapabilities\n /** Shared allowance mode for the ERC20 and Permit2 approval steps. Defaults to the requested amount. */\n readonly approveAmountType?: 'exact' | 'max'\n}\n\nexport interface RouterPermit2AuthorizationPlan {\n readonly actions: readonly TransactionAction[]\n readonly signatureActionId?: string\n readonly permitSingle?: unknown\n readonly mode: 'none' | 'typed-data' | 'on-chain' | 'already-approved'\n}\n\nasync function hasTypedDataCapability(\n context: ProtocolsContext,\n capabilities: WalletCapabilities | undefined,\n): Promise<boolean> {\n if (capabilities) return capabilities.signTypedData\n return (await context.runtime?.getWallet())?.capabilities.signTypedData === true\n}\n\nfunction normalizePlanDeadlineValue(value: string | number | bigint): string | number {\n return typeof value === 'bigint' ? value.toString() : value\n}\n\nconst MAX_UINT160 = '1461501637330902918203684832716283019655932542975'\n\nexport async function planRouterPermit2Authorization(\n context: ProtocolsContext,\n input: RouterPermit2AuthorizationInput,\n): Promise<RouterPermit2AuthorizationPlan> {\n if (input.approval === 'none') {\n return { actions: [], mode: 'none' }\n }\n\n const helper = context.chain.contracts.permit2Helper\n if (!helper) {\n throw new SDKError('SDK_INVALID_ARGUMENT', `Permit2Helper is not configured for ${context.network}`, {\n network: context.network,\n contract: 'permit2Helper',\n })\n }\n const runtime = requireRuntime(context, 'Router Permit2 authorization')\n const actions: TransactionAction[] = []\n const token = assertTronAddress(input.token, 'token')\n const spender = input.spender\n ? assertTronAddress(input.spender, 'spender')\n : context.chain.contracts.universalRouter\n\n const tokenApproval = await planApproval(context, {\n asset: { type: 'token', token },\n owner: input.owner,\n spender: context.chain.contracts.permit2,\n amount: input.amount,\n }, {\n mode: 'auto',\n amount: input.approveAmountType ?? 'exact',\n })\n actions.push(...tokenApproval.actions)\n\n const approved = normalizePermit2HelperResult(await runtime.readContract(buildPermit2HelperRead({\n helper,\n permit2: context.chain.contracts.permit2,\n owner: input.owner,\n token,\n spender,\n amount: input.amount,\n })))\n const permit2Amount = input.approveAmountType === 'max'\n ? MAX_UINT160\n : input.amount\n\n if (approved) {\n return { actions, mode: 'already-approved' }\n }\n\n const expiration = normalizeDeadline(context, {\n ttlSeconds: input.ttlSeconds ?? 30 * 24 * 60 * 60,\n ...(input.deadline !== undefined\n ? { deadline: normalizePlanDeadlineValue(input.deadline) }\n : {}),\n }).toString()\n const sigDeadline = normalizeDeadline(context, { ttlSeconds: 3_600 }).toString()\n\n if (\n (input.approval === 'auto' || input.approval === 'permit2') &&\n await hasTypedDataCapability(context, input.walletCapabilities)\n ) {\n // Only signature construction needs the nonce; approval validity comes from the helper.\n const allowance = normalizePermit2Allowance(await runtime.readContract(buildPermit2AllowanceRead({\n permit2: context.chain.contracts.permit2,\n owner: input.owner,\n token,\n spender,\n })))\n const typedData = buildPermit2TypedData({\n network: context.network,\n permit2: context.chain.contracts.permit2,\n owner: input.owner,\n token,\n spender,\n amount: permit2Amount,\n expiration,\n sigDeadline,\n nonce: allowance.nonce.toString(),\n })\n const signatureActionId = `${nextPlanId(context, 'permit2')}-signature`\n actions.push(createTypedDataSignatureAction({\n id: signatureActionId,\n typedData,\n }))\n return {\n actions,\n signatureActionId,\n permitSingle: typedData.message,\n mode: 'typed-data',\n }\n }\n\n if (input.approval === 'permit2' || input.approval === 'auto' || input.approval === 'approve') {\n actions.push(buildPermit2ApproveAction({\n id: `${nextPlanId(context, 'permit2')}-approve`,\n permit2: context.chain.contracts.permit2,\n token,\n spender,\n amount: permit2Amount,\n expiration,\n }))\n return { actions, mode: 'on-chain' }\n }\n\n throw new SDKError(\n 'SDK_INVALID_ARGUMENT',\n 'Unsupported approval mode for Router Permit2 authorization',\n { approval: input.approval },\n )\n}\n","import {\n SDKError,\n createContractCallAction,\n type ContractCallAction,\n type Network,\n type TronAddress,\n} from '@sun-protocol/sun-sdk-core'\nimport type { TypedDataPayload, ContractRead } from '@sun-protocol/sun-sdk-runtime'\nimport { PERMIT_TYPES, toEvmHex } from '@sun-protocol/permit2-sdk'\n\nconst PERMIT2_TYPED_DATA_CHAIN_IDS: Record<Network, number> = {\n mainnet: 728126428,\n nile: 3448148188,\n}\n\nexport interface Permit2Allowance {\n readonly amount: bigint\n readonly expiration: bigint\n readonly nonce: bigint\n}\n\n/** The helper evaluates allowance amount and expiration against chain state/time. */\nexport function buildPermit2HelperRead(input: {\n readonly helper: TronAddress\n readonly permit2: TronAddress\n readonly owner: TronAddress\n readonly token: TronAddress\n readonly spender: TronAddress\n readonly amount: string\n}): ContractRead {\n return {\n target: input.helper,\n functionSelector: 'checkPermit2Allowance(address,address,address,address,uint256)',\n parameters: [\n { type: 'address', value: input.permit2 },\n { type: 'address', value: input.token },\n { type: 'address', value: input.owner },\n { type: 'address', value: input.spender },\n { type: 'uint256', value: input.amount },\n ],\n outputs: [{ type: 'bool', name: 'approved' }],\n }\n}\n\nexport function normalizePermit2HelperResult(result: unknown): boolean {\n if (typeof result === 'boolean') return result\n if (Array.isArray(result) && result.length === 1 && typeof result[0] === 'boolean') return result[0]\n throw new SDKError('SDK_CONTRACT_ERROR', 'Invalid Permit2Helper approval result', { result })\n}\n\nexport function buildPermit2AllowanceRead(input: {\n readonly permit2: TronAddress\n readonly owner: TronAddress\n readonly token: TronAddress\n readonly spender: TronAddress\n}): ContractRead {\n return {\n target: input.permit2,\n functionSelector: 'allowance(address,address,address)',\n parameters: [\n { type: 'address', value: input.owner },\n { type: 'address', value: input.token },\n { type: 'address', value: input.spender },\n ],\n outputs: [\n { type: 'uint160', name: 'amount' },\n { type: 'uint48', name: 'expiration' },\n { type: 'uint48', name: 'nonce' },\n ],\n }\n}\n\nfunction bigintFrom(value: unknown, label: string): bigint {\n if (typeof value === 'bigint') return value\n if (typeof value === 'number' && Number.isSafeInteger(value)) return BigInt(value)\n if (typeof value === 'string' && /^[0-9]+$/.test(value)) return BigInt(value)\n throw new SDKError('SDK_CONTRACT_ERROR', `Invalid Permit2 allowance ${label}`, { value })\n}\n\nexport function normalizePermit2Allowance(result: unknown): Permit2Allowance {\n if (Array.isArray(result)) {\n return {\n amount: bigintFrom(result[0], 'amount'),\n expiration: bigintFrom(result[1], 'expiration'),\n nonce: bigintFrom(result[2], 'nonce'),\n }\n }\n\n if (typeof result === 'object' && result !== null) {\n const value = result as Record<string, unknown>\n return {\n amount: bigintFrom(value.amount ?? value[0], 'amount'),\n expiration: bigintFrom(value.expiration ?? value[1], 'expiration'),\n nonce: bigintFrom(value.nonce ?? value[2], 'nonce'),\n }\n }\n\n throw new SDKError('SDK_CONTRACT_ERROR', 'Invalid Permit2 allowance result', { result })\n}\n\nexport interface Permit2TypedDataInput {\n readonly network: Network\n readonly permit2: TronAddress\n readonly owner: TronAddress\n readonly token: TronAddress\n readonly spender: TronAddress\n readonly amount: string\n readonly expiration: string\n readonly sigDeadline: string\n readonly nonce: string\n}\n\nexport function buildPermit2TypedData(input: Permit2TypedDataInput): TypedDataPayload {\n return {\n primaryType: 'PermitSingle',\n domain: {\n name: 'Permit2',\n chainId: PERMIT2_TYPED_DATA_CHAIN_IDS[input.network],\n verifyingContract: toEvmHex(input.permit2),\n },\n types: PERMIT_TYPES,\n message: {\n details: {\n token: toEvmHex(input.token),\n amount: input.amount,\n expiration: input.expiration,\n nonce: input.nonce,\n },\n spender: toEvmHex(input.spender),\n sigDeadline: input.sigDeadline,\n },\n }\n}\n\nexport function buildPermit2ApproveAction(input: {\n readonly id: string\n readonly permit2: TronAddress\n readonly token: TronAddress\n readonly spender: TronAddress\n readonly amount: string\n readonly expiration: string\n}): ContractCallAction {\n return createContractCallAction({\n id: input.id,\n target: input.permit2,\n functionSelector: 'approve(address,address,uint160,uint48)',\n waitForReceipt: 'included',\n parameters: [\n { type: 'address', value: input.token },\n { type: 'address', value: input.spender },\n { type: 'uint160', value: input.amount },\n { type: 'uint48', value: input.expiration },\n ],\n })\n}\n"],"mappings":"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","names":["SDKError","SDKError"]}