@opensea/cli 1.0.0 → 1.1.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.
package/README.md CHANGED
@@ -41,14 +41,15 @@ npx @opensea/cli collections get mfers
41
41
  Set your API key via environment variable or flag:
42
42
 
43
43
  ```bash
44
- export OPENSEA_API_KEY=your-api-key
44
+ # Get an instant free-tier API key (no signup needed)
45
+ export OPENSEA_API_KEY=$(curl -s -X POST https://api.opensea.io/api/v2/auth/keys | jq -r '.api_key')
45
46
  opensea collections get mfers
46
47
 
47
48
  # or pass inline
48
49
  opensea --api-key your-api-key collections get mfers
49
50
  ```
50
51
 
51
- Get an API key at [docs.opensea.io](https://docs.opensea.io/reference/api-keys).
52
+ Get an API key instantly via the command above, or get a full key at [opensea.io/settings/developer](https://opensea.io/settings/developer) for higher rate limits. See [API key docs](https://docs.opensea.io/reference/api-keys) for details.
52
53
 
53
54
  ## Quick Start
54
55
 
@@ -174,7 +175,7 @@ console.log(formatToon(data))
174
175
  ## Requirements
175
176
 
176
177
  - Node.js >= 18.0.0
177
- - OpenSea API key ([get one here](https://docs.opensea.io/reference/api-keys))
178
+ - OpenSea API key get one instantly: `curl -s -X POST https://api.opensea.io/api/v2/auth/keys | jq -r '.api_key'` or from [opensea.io/settings/developer](https://opensea.io/settings/developer)
178
179
 
179
180
  ## Development
180
181
 
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ import { Command as Command13 } from "commander";
6
6
  // src/client.ts
7
7
  var DEFAULT_BASE_URL = "https://api.opensea.io";
8
8
  var DEFAULT_TIMEOUT_MS = 3e4;
9
- var USER_AGENT = `opensea-cli/${"1.0.0"}`;
9
+ var USER_AGENT = `opensea-cli/${"1.1.0"}`;
10
10
  var DEFAULT_MAX_RETRIES = 0;
11
11
  var DEFAULT_RETRY_BASE_DELAY_MS = 1e3;
12
12
  function isRetryableStatus(status, method) {
@@ -1954,23 +1954,24 @@ function createWalletFromEnv(provider) {
1954
1954
  if (provider) {
1955
1955
  return createAdapter(provider);
1956
1956
  }
1957
- const hasTurnkey = !!process.env.TURNKEY_API_PUBLIC_KEY && !!process.env.TURNKEY_ORGANIZATION_ID;
1957
+ const hasPrivy = !!process.env.PRIVY_APP_ID && !!process.env.PRIVY_APP_SECRET;
1958
1958
  const hasFireblocks = !!process.env.FIREBLOCKS_API_KEY && !!process.env.FIREBLOCKS_VAULT_ID;
1959
+ const hasTurnkey = !!process.env.TURNKEY_API_PUBLIC_KEY && !!process.env.TURNKEY_ORGANIZATION_ID;
1959
1960
  const hasPrivateKey = !!process.env.PRIVATE_KEY && !!process.env.RPC_URL;
1960
- const hasPrivy = !!process.env.PRIVY_APP_ID && !!process.env.PRIVY_APP_SECRET;
1961
1961
  const detected = [
1962
- hasTurnkey && "turnkey",
1962
+ hasPrivy && "privy",
1963
1963
  hasFireblocks && "fireblocks",
1964
- hasPrivateKey && "private-key",
1965
- hasPrivy && "privy"
1964
+ hasTurnkey && "turnkey",
1965
+ hasPrivateKey && "private-key"
1966
1966
  ].filter(Boolean);
1967
1967
  if (detected.length > 1) {
1968
1968
  console.warn(
1969
1969
  `WARNING: Multiple wallet providers detected: ${detected.join(", ")}. Using ${detected[0]}. Set --wallet-provider explicitly to avoid ambiguity.`
1970
1970
  );
1971
1971
  }
1972
- if (hasTurnkey) return TurnkeyAdapter.fromEnv();
1972
+ if (hasPrivy) return PrivyAdapter.fromEnv();
1973
1973
  if (hasFireblocks) return FireblocksAdapter.fromEnv();
1974
+ if (hasTurnkey) return TurnkeyAdapter.fromEnv();
1974
1975
  if (hasPrivateKey) return PrivateKeyAdapter.fromEnv();
1975
1976
  return PrivyAdapter.fromEnv();
1976
1977
  }
@@ -1992,6 +1993,30 @@ function createAdapter(provider) {
1992
1993
  }
1993
1994
 
1994
1995
  // src/sdk.ts
1996
+ function convertToSmallestUnit(amount, decimals) {
1997
+ const [whole = "0", frac = ""] = amount.split(".");
1998
+ if (frac.length > decimals) {
1999
+ throw new Error(
2000
+ `Too many decimal places (${frac.length}) for token with ${decimals} decimals`
2001
+ );
2002
+ }
2003
+ const paddedFrac = frac.padEnd(decimals, "0");
2004
+ return (BigInt(whole) * BigInt(10) ** BigInt(decimals) + BigInt(paddedFrac)).toString();
2005
+ }
2006
+ async function resolveQuantity(client, chain, tokenAddress, quantity) {
2007
+ if (/^\d+$/.test(quantity)) {
2008
+ return quantity;
2009
+ }
2010
+ if (!/^\d+\.\d+$/.test(quantity)) {
2011
+ throw new Error(
2012
+ `Invalid quantity "${quantity}": must be an integer or decimal number`
2013
+ );
2014
+ }
2015
+ const token = await client.get(
2016
+ `/api/v2/chain/${chain}/token/${tokenAddress}`
2017
+ );
2018
+ return convertToSmallestUnit(quantity, token.decimals);
2019
+ }
1995
2020
  var SwapsAPI = class {
1996
2021
  constructor(client) {
1997
2022
  this.client = client;
@@ -2067,7 +2092,10 @@ function swapsCommand(getClient2, getFormat2) {
2067
2092
  ).requiredOption("--to-chain <chain>", "Chain of the token to swap to").requiredOption(
2068
2093
  "--to-address <address>",
2069
2094
  "Contract address of the token to swap to"
2070
- ).requiredOption("--quantity <quantity>", "Amount to swap (in token units)").requiredOption("--address <address>", "Wallet address executing the swap").option(
2095
+ ).requiredOption(
2096
+ "--quantity <quantity>",
2097
+ "Amount to swap (decimals like 0.1 are auto-converted to smallest units)"
2098
+ ).requiredOption("--address <address>", "Wallet address executing the swap").option(
2071
2099
  "--slippage <slippage>",
2072
2100
  "Slippage tolerance (0.0 to 0.5, default: 0.01)"
2073
2101
  ).option(
@@ -2076,6 +2104,12 @@ function swapsCommand(getClient2, getFormat2) {
2076
2104
  ).action(
2077
2105
  async (options) => {
2078
2106
  const client = getClient2();
2107
+ const quantity = await resolveQuantity(
2108
+ client,
2109
+ options.fromChain,
2110
+ options.fromAddress,
2111
+ options.quantity
2112
+ );
2079
2113
  const result = await client.get(
2080
2114
  "/api/v2/swap/quote",
2081
2115
  {
@@ -2083,7 +2117,7 @@ function swapsCommand(getClient2, getFormat2) {
2083
2117
  from_address: options.fromAddress,
2084
2118
  to_chain: options.toChain,
2085
2119
  to_address: options.toAddress,
2086
- quantity: options.quantity,
2120
+ quantity,
2087
2121
  address: options.address,
2088
2122
  slippage: options.slippage ? parseFloatOption(options.slippage, "--slippage") : void 0,
2089
2123
  recipient: options.recipient
@@ -2100,7 +2134,10 @@ function swapsCommand(getClient2, getFormat2) {
2100
2134
  ).requiredOption("--to-chain <chain>", "Chain of the token to swap to").requiredOption(
2101
2135
  "--to-address <address>",
2102
2136
  "Contract address of the token to swap to"
2103
- ).requiredOption("--quantity <quantity>", "Amount to swap (in token units)").option(
2137
+ ).requiredOption(
2138
+ "--quantity <quantity>",
2139
+ "Amount to swap (decimals like 0.1 are auto-converted to smallest units)"
2140
+ ).option(
2104
2141
  "--slippage <slippage>",
2105
2142
  "Slippage tolerance (0.0 to 0.5, default: 0.01)"
2106
2143
  ).option(
@@ -2116,12 +2153,20 @@ function swapsCommand(getClient2, getFormat2) {
2116
2153
  );
2117
2154
  const address = await wallet.getAddress();
2118
2155
  console.error(`Using ${wallet.name} wallet: ${address}`);
2119
- const swaps = new SwapsAPI(getClient2());
2156
+ const client = getClient2();
2157
+ const quantity = await resolveQuantity(
2158
+ client,
2159
+ options.fromChain,
2160
+ options.fromAddress,
2161
+ options.quantity
2162
+ );
2163
+ const swaps = new SwapsAPI(client);
2120
2164
  const format = getFormat2();
2121
2165
  const slippage = options.slippage ? parseFloatOption(options.slippage, "--slippage") : void 0;
2122
2166
  if (options.dryRun) {
2123
2167
  const quote = await swaps.quote({
2124
2168
  ...options,
2169
+ quantity,
2125
2170
  address,
2126
2171
  slippage
2127
2172
  });
@@ -2131,6 +2176,7 @@ function swapsCommand(getClient2, getFormat2) {
2131
2176
  const results = await swaps.execute(
2132
2177
  {
2133
2178
  ...options,
2179
+ quantity,
2134
2180
  address,
2135
2181
  slippage
2136
2182
  },
@@ -2216,7 +2262,7 @@ var BANNER = `
2216
2262
  |_|
2217
2263
  `;
2218
2264
  var program = new Command13();
2219
- program.name("opensea").description("OpenSea CLI - Query the OpenSea API from the command line").version(process.env.npm_package_version ?? "0.0.0").addHelpText("before", BANNER).option("--api-key <key>", "OpenSea API key (or set OPENSEA_API_KEY env var)").option("--chain <chain>", "Default chain", "ethereum").option("--format <format>", "Output format (json, table, or toon)", "json").option("--base-url <url>", "API base URL").option("--timeout <ms>", "Request timeout in milliseconds", "30000").option("--verbose", "Log request and response info to stderr").option(
2265
+ program.name("opensea").description("OpenSea CLI - Query the OpenSea API from the command line").version("1.1.0").addHelpText("before", BANNER).option("--api-key <key>", "OpenSea API key (or set OPENSEA_API_KEY env var)").option("--chain <chain>", "Default chain", "ethereum").option("--format <format>", "Output format (json, table, or toon)", "json").option("--base-url <url>", "API base URL").option("--timeout <ms>", "Request timeout in milliseconds", "30000").option("--verbose", "Log request and response info to stderr").option(
2220
2266
  "--fields <fields>",
2221
2267
  "Comma-separated list of fields to include in output"
2222
2268
  ).option("--max-lines <lines>", "Truncate output after N lines").option("--max-retries <n>", "Max retries on 429/5xx (0 to disable)", "3").option("--no-retry", "Disable request retries");