{"version":3,"file":"near-cli.cjs","names":["Effect"],"sources":["../src/near-cli.ts"],"sourcesContent":["import { generateKeyPairSync } from \"node:crypto\";\nimport { Effect } from \"effect\";\nimport { execa } from \"execa\";\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: boolean;\n  txHash?: string;\n  error?: 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 NearCliInstallError extends Error {\n  readonly _tag = \"NearCliInstallError\";\n  constructor(message: string) {\n    super(`Failed to install NEAR CLI: ${message}`);\n  }\n}\n\nexport class NearTransactionError extends Error {\n  readonly _tag = \"NearTransactionError\";\n}\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\nconst installNearCli = Effect.tryPromise({\n  try: async () => {\n    await execa(\"sh\", [\"-c\", `curl --proto '=https' --tlsv1.2 -LsSf ${INSTALLER_URL} | sh`], {\n      stdio: \"inherit\",\n    });\n  },\n  catch: (error) => {\n    if (error instanceof Error && \"exitCode\" in error) {\n      return new NearCliInstallError(\n        `Installer exited with code ${(error as { exitCode: number }).exitCode}`,\n      );\n    }\n    return new NearCliInstallError(error instanceof Error ? error.message : String(error));\n  },\n});\n\nasync function runNearCommand(args: string[]): Promise<void> {\n  await execa(\"near\", args, { stdio: \"inherit\" });\n}\n\nexport const ensureNearCli = Effect.gen(function* () {\n  const isInstalled = yield* checkNearCliInstalled;\n  if (isInstalled) return;\n\n  if (process.env.BOS_INSTALL_NEAR_CLI === \"true\") {\n    yield* installNearCli;\n    return;\n  }\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\nexport const executeTransaction = (\n  config: NearTransactionConfig,\n): Effect.Effect<NearTransactionResult, Error> =>\n  Effect.gen(function* () {\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 (config.privateKey) {\n      args.push(\"sign-with-plaintext-private-key\", config.privateKey, \"send\");\n    } else {\n      args.push(\"sign-with-keychain\", \"send\");\n    }\n\n    const output = yield* Effect.tryPromise({\n      try: async () => {\n        const result = await execa(\"near\", args, {\n          stdin: \"inherit\",\n          stdout: \"pipe\",\n          stderr: \"pipe\",\n          reject: false,\n        });\n\n        process.stdout.write(result.stdout);\n        const combined = `${result.stdout}\\n${result.stderr}`;\n        const txHashMatch = combined.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n        const hasCodeDoesNotExist = /CodeDoesNotExist/i.test(combined);\n        const hasTransactionFailed = /Transaction failed/i.test(combined);\n        const softSuccess =\n          Boolean(txHashMatch?.[1]) && hasCodeDoesNotExist && hasTransactionFailed;\n\n        if (result.exitCode === 0 || softSuccess) {\n          if (softSuccess) {\n            console.log(`  ${txHashMatch?.[1]} — FastDATA CodeDoesNotExist (expected)`);\n          }\n          return combined;\n        }\n\n        throw new NearTransactionError(\n          result.stderr || `Transaction failed with code ${result.exitCode}`,\n        );\n      },\n      catch: (error) => error as Error,\n    });\n\n    const txHashMatch = output.match(/Transaction ID:\\s*([A-Za-z0-9]+)/i);\n\n    return {\n      success: true,\n      txHash: txHashMatch?.[1],\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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"}