{"version":3,"file":"near-cli.cjs","names":["Effect","colors"],"sources":["../src/near-cli.ts"],"sourcesContent":["import { generateKeyPairSync } from \"node:crypto\";\nimport { Effect } from \"effect\";\nimport { execa } from \"execa\";\nimport { colors } from \"./utils/theme\";\n\nexport interface NearTransactionConfig {\n  account: string;\n  contract: string;\n  method: string;\n  argsBase64: string;\n  network?: \"mainnet\" | \"testnet\";\n  privateKey?: string;\n  gas?: string;\n  deposit?: string;\n}\n\nexport interface NearTransactionResult {\n  success: true;\n  txHash?: string;\n  output?: string;\n}\n\nexport interface NearKeyPair {\n  publicKey: string;\n  privateKey: string;\n}\n\nexport interface FunctionCallAccessKeyConfig {\n  account: string;\n  contract: string;\n  allowance: string;\n  functionNames: string[];\n  network?: \"mainnet\" | \"testnet\";\n}\n\nconst NEAR_CLI_VERSION = \"0.23.5\";\nconst INSTALLER_URL = `https://github.com/near/near-cli-rs/releases/download/v${NEAR_CLI_VERSION}/near-cli-rs-installer.sh`;\nconst BASE58_ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\nexport class NearCliNotFoundError extends Error {\n  readonly _tag = \"NearCliNotFoundError\";\n  constructor() {\n    super(\"NEAR CLI not found\");\n  }\n}\n\nexport class NearTransactionError extends Error {\n  readonly _tag = \"NearTransactionError\";\n}\n\nexport type NearSigningMode =\n  | { _tag: \"privateKey\"; privateKey: string }\n  | { _tag: \"interactiveKeychain\" };\n\nfunction base64UrlToBytes(input: string): Uint8Array {\n  const normalized = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n  return new Uint8Array(Buffer.from(normalized, \"base64\"));\n}\n\nfunction base58Encode(input: Uint8Array): string {\n  if (input.length === 0) return \"\";\n\n  const digits: number[] = [0];\n  for (const byte of input) {\n    let carry = byte;\n    for (let i = 0; i < digits.length; i++) {\n      carry += digits[i]! << 8;\n      digits[i] = carry % 58;\n      carry = Math.floor(carry / 58);\n    }\n    while (carry > 0) {\n      digits.push(carry % 58);\n      carry = Math.floor(carry / 58);\n    }\n  }\n\n  let output = \"\";\n  for (const byte of input) {\n    if (byte === 0) output += BASE58_ALPHABET[0];\n    else break;\n  }\n\n  for (let i = digits.length - 1; i >= 0; i--) {\n    output += BASE58_ALPHABET[digits[i]!]!;\n  }\n\n  return output;\n}\n\nexport function generateNearKeyPair(): NearKeyPair {\n  const { publicKey, privateKey } = generateKeyPairSync(\"ed25519\");\n  const publicJwk = publicKey.export({ format: \"jwk\" }) as JsonWebKey;\n  const privateJwk = privateKey.export({ format: \"jwk\" }) as JsonWebKey;\n\n  if (!publicJwk.x || !privateJwk.d) {\n    throw new Error(\"Failed to generate NEAR keypair\");\n  }\n\n  const publicBytes = base64UrlToBytes(publicJwk.x);\n  const privateSeed = base64UrlToBytes(privateJwk.d);\n  const secretBytes = new Uint8Array(privateSeed.length + publicBytes.length);\n  secretBytes.set(privateSeed, 0);\n  secretBytes.set(publicBytes, privateSeed.length);\n\n  return {\n    publicKey: `ed25519:${base58Encode(publicBytes)}`,\n    privateKey: `ed25519:${base58Encode(secretBytes)}`,\n  };\n}\n\nconst checkNearCliInstalled = Effect.tryPromise({\n  try: async () => {\n    try {\n      await execa(\"near\", [\"--version\"], { stdio: \"pipe\" });\n      return true;\n    } catch {\n      return false;\n    }\n  },\n  catch: () => new Error(\"Failed to check NEAR CLI\"),\n});\n\nasync function runNearCommand(args: string[]): Promise<void> {\n  if (!process.stdin.isTTY) {\n    throw new NearTransactionError(\n      \"No TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n    );\n  }\n\n  await execa(\"near\", args, { stdin: \"inherit\", stdout: \"inherit\", stderr: \"inherit\" });\n}\n\nexport function resolveNearSigningMode(privateKey?: string): NearSigningMode {\n  if (privateKey) {\n    return { _tag: \"privateKey\", privateKey };\n  }\n\n  if (!process.stdin.isTTY) {\n    throw new NearTransactionError(\n      \"No private key provided and no TTY available for keychain signing. Set NEAR_PRIVATE_KEY environment variable to sign locally.\",\n    );\n  }\n\n  console.log(\n    colors.yellow(\n      \"  Warning: No NEAR_PRIVATE_KEY set — falling back to interactive keychain signing.\",\n    ),\n  );\n  return { _tag: \"interactiveKeychain\" };\n}\n\nexport const ensureNearCli = Effect.gen(function* () {\n  const isInstalled = yield* checkNearCliInstalled;\n  if (isInstalled) return;\n\n  console.log();\n  console.log(\"  NEAR CLI not found\");\n\n  console.log();\n  console.log(`  To install manually: curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`);\n  console.log();\n  yield* Effect.fail(new NearCliNotFoundError());\n});\n\nfunction combineNearOutput(stdout?: string, stderr?: string): string {\n  return [stdout, stderr].filter((value) => value && value.trim().length > 0).join(\"\\n\");\n}\n\nfunction extractTransactionHash(output: string): string | undefined {\n  const match = output.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n  return match?.[1];\n}\n\nexport const executeTransaction = (\n  config: NearTransactionConfig,\n  signingMode?: NearSigningMode,\n): Effect.Effect<NearTransactionResult, Error> =>\n  Effect.gen(function* () {\n    const resolvedSigningMode = signingMode ?? resolveNearSigningMode(config.privateKey);\n    const gas = (config.gas || \"300Tgas\").replace(/\\s+/g, \"\");\n    const deposit = (config.deposit || \"0NEAR\").replace(/\\s+/g, \"\");\n    const network = config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\");\n\n    const args = [\n      \"contract\",\n      \"call-function\",\n      \"as-transaction\",\n      config.contract,\n      config.method,\n      \"base64-args\",\n      config.argsBase64,\n      \"prepaid-gas\",\n      gas,\n      \"attached-deposit\",\n      deposit,\n      \"sign-as\",\n      config.account,\n      \"network-config\",\n      network,\n    ];\n\n    if (resolvedSigningMode._tag === \"privateKey\") {\n      args.push(\"sign-with-plaintext-private-key\", resolvedSigningMode.privateKey, \"send\");\n    } else {\n      args.push(\"sign-with-keychain\", \"send\");\n    }\n\n    const output = yield* Effect.tryPromise({\n      try: async () => {\n        const isPrivateKeyMode = resolvedSigningMode._tag === \"privateKey\";\n        const proc = execa(\"near\", args, {\n          stdin: isPrivateKeyMode ? \"ignore\" : \"inherit\",\n          stdout: isPrivateKeyMode ? \"pipe\" : \"inherit\",\n          stderr: isPrivateKeyMode ? \"pipe\" : \"inherit\",\n          reject: false,\n          timeout: 5 * 60 * 1000,\n        });\n\n        if (isPrivateKeyMode) {\n          proc.stdout?.on(\"data\", (chunk: Buffer) => {\n            process.stdout.write(chunk);\n          });\n\n          proc.stderr?.on(\"data\", (chunk: Buffer) => {\n            process.stderr.write(chunk);\n          });\n        }\n\n        const result = await proc;\n        const combined = combineNearOutput(result.stdout, result.stderr);\n        const txHash = extractTransactionHash(combined);\n        const hasCodeDoesNotExist = /CodeDoesNotExist/i.test(combined);\n        const hasTransactionFailed = /Transaction failed/i.test(combined);\n        const softSuccess = Boolean(txHash) && hasCodeDoesNotExist && hasTransactionFailed;\n\n        if (result.exitCode === 0 || softSuccess) {\n          if (softSuccess) {\n            console.log(`  ${txHash} — FastDATA CodeDoesNotExist (expected)`);\n          }\n          return {\n            success: true,\n            txHash,\n            output: combined || undefined,\n          };\n        }\n\n        throw new NearTransactionError(\n          combined || `Transaction failed with code ${result.exitCode}`,\n        );\n      },\n      catch: (error) => error as Error,\n    });\n\n    return {\n      success: true,\n      txHash: output.txHash,\n      output: output.output,\n    };\n  });\n\nexport async function addFunctionCallAccessKey(\n  config: FunctionCallAccessKeyConfig,\n): Promise<NearKeyPair> {\n  const keyPair = generateNearKeyPair();\n  const args = [\n    \"account\",\n    \"add-key\",\n    config.account,\n    \"grant-function-call-access\",\n    \"--allowance\",\n    config.allowance,\n    \"--contract-account-id\",\n    config.contract,\n    \"--function-names\",\n    config.functionNames.join(\", \"),\n    \"use-manually-provided-public-key\",\n    keyPair.publicKey,\n    \"network-config\",\n    config.network || (config.account.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\"),\n    \"sign-with-keychain\",\n    \"send\",\n  ];\n\n  await runNearCommand(args);\n  return keyPair;\n}\n"],"mappings":"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"}