@alchemy/x402 0.2.0 → 0.4.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
@@ -12,22 +12,29 @@ pnpm add @alchemy/x402
12
12
 
13
13
  ```bash
14
14
  # Generate a new wallet
15
- npx alchemy-x402 wallet generate
15
+ npx @alchemy/x402 wallet generate
16
16
 
17
- # Import an existing wallet (accepts key or file path)
18
- npx alchemy-x402 wallet import --private-key <key>
17
+ # Import an existing wallet (accepts hex key or path to a key file)
18
+ npx @alchemy/x402 wallet import --private-key 0xac09...
19
+ npx @alchemy/x402 wallet import --private-key /path/to/keyfile
19
20
 
20
21
  # Generate a SIWE token
21
- npx alchemy-x402 sign-siwe --private-key <key> --expires-after 1h
22
+ npx @alchemy/x402 sign-siwe --private-key /path/to/keyfile --expires-after 1h
22
23
 
23
24
  # Create an x402 payment from a PAYMENT-REQUIRED header
24
- npx alchemy-x402 pay --private-key <key> --payment-required <header>
25
+ npx @alchemy/x402 pay --private-key /path/to/keyfile --payment-required <header>
25
26
  ```
26
27
 
27
28
  ## Library
28
29
 
29
30
  ```ts
30
- import { signSiwe, generateWallet, getWalletAddress, createPayment, buildX402Client } from "@alchemy/x402";
31
+ import {
32
+ signSiwe,
33
+ generateWallet,
34
+ getWalletAddress,
35
+ createPayment,
36
+ buildX402Client,
37
+ } from "@alchemy/x402";
31
38
  ```
32
39
 
33
40
  ### Generate a wallet
@@ -90,56 +97,6 @@ All commands and functions accept private keys as:
90
97
  - Raw hex string: `ac09...`
91
98
  - File path: `/path/to/keyfile`
92
99
 
93
- ## Development
94
-
95
- ### Prerequisites
96
-
97
- - Node.js >= 20
98
- - [pnpm](https://pnpm.io/)
99
-
100
- **Option A** — [mise](https://mise.jdx.dev/) (recommended, installs both Node and pnpm from `.tool-versions`):
101
-
102
- ```bash
103
- mise install
104
- ```
105
-
106
- **Option B** — [corepack](https://nodejs.org/api/corepack.html) (ships with Node, reads `packageManager` from package.json):
107
-
108
- ```bash
109
- corepack enable
110
- ```
111
-
112
- ### Getting started
113
-
114
- ```bash
115
- git clone git@github.com:alchemyplatform/alchemy-x402.git
116
- cd alchemy-x402
117
- pnpm install
118
- pnpm run build
119
- pnpm run typecheck
120
- pnpm test
121
- ```
122
-
123
100
  ## For maintainers
124
101
 
125
- ### Adding a changeset
126
-
127
- This project uses [Changesets](https://github.com/changesets/changesets) for versioning and npm publishing.
128
-
129
- When your PR includes a user-facing change, add a changeset:
130
-
131
- ```bash
132
- pnpm run changeset
133
- ```
134
-
135
- Select the semver bump type (patch/minor/major) and describe the change. Commit the generated `.changeset/*.md` file with your PR.
136
-
137
- ### Release flow
138
-
139
- 1. Merge PRs with changeset files to `main`
140
- 2. CI automatically opens a "Version Packages" PR that bumps the version and updates `CHANGELOG.md`
141
- 3. Merge the version PR to publish to npm
142
-
143
- ### Secrets
144
-
145
- Add an `NPM_PUBLISH_TOKEN` secret to the repo (**Settings > Secrets and variables > Actions**) with a token from [npmjs.com](https://www.npmjs.com/settings/~/tokens).
102
+ See [MAINTAINERS.md](./MAINTAINERS.md).
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire } from "module";
2
3
  import { Command } from "@commander-js/extra-typings";
3
4
  import { randomBytes } from "crypto";
4
5
  import ms from "ms";
@@ -63,7 +64,7 @@ async function signSiwe(opts) {
63
64
 
64
65
  //#endregion
65
66
  //#region src/cli/commands/sign-siwe.ts
66
- const signSiweCommand = new Command("sign-siwe").description("Generate a SIWE authentication token").requiredOption("--private-key <key>", "Wallet private key").option("--expires-after <duration>", "Token expiration duration (e.g. 1h, 30m, 7d)", "1h").action(async (opts) => {
67
+ const signSiweCommand = new Command("sign-siwe").description("Generate a SIWE authentication token").requiredOption("--private-key <key-or-path>", "Wallet private key (hex string or path to a key file)").option("--expires-after <duration>", "Token expiration duration (e.g. 1h, 30m, 7d)", "1h").action(async (opts) => {
67
68
  const token = await signSiwe({
68
69
  privateKey: opts.privateKey,
69
70
  expiresAfter: opts.expiresAfter
@@ -78,7 +79,7 @@ walletCommand.command("generate").description("Generate a new wallet").action(()
78
79
  const wallet = generateWallet();
79
80
  console.log(JSON.stringify(wallet, null, 2));
80
81
  });
81
- walletCommand.command("import").description("Import an existing wallet and display its address").requiredOption("--private-key <key>", "Wallet private key").action((opts) => {
82
+ walletCommand.command("import").description("Import an existing wallet and display its address").requiredOption("--private-key <key-or-path>", "Wallet private key (hex string or path to a key file)").action((opts) => {
82
83
  const address = getWalletAddress(opts.privateKey);
83
84
  console.log(JSON.stringify({ address }, null, 2));
84
85
  });
@@ -113,7 +114,7 @@ async function createPayment(opts) {
113
114
 
114
115
  //#endregion
115
116
  //#region src/cli/commands/pay.ts
116
- const payCommand = new Command("pay").description("Create an x402 payment from a PAYMENT-REQUIRED header").requiredOption("--private-key <key>", "Wallet private key").requiredOption("--payment-required <header>", "Raw PAYMENT-REQUIRED header value").action(async (opts) => {
117
+ const payCommand = new Command("pay").description("Create an x402 payment from a PAYMENT-REQUIRED header").requiredOption("--private-key <key-or-path>", "Wallet private key (hex string or path to a key file)").requiredOption("--payment-required <header>", "Raw PAYMENT-REQUIRED header value").action(async (opts) => {
117
118
  const paymentHeader = await createPayment({
118
119
  privateKey: opts.privateKey,
119
120
  paymentRequiredHeader: opts.paymentRequired
@@ -123,7 +124,8 @@ const payCommand = new Command("pay").description("Create an x402 payment from a
123
124
 
124
125
  //#endregion
125
126
  //#region src/cli/index.ts
126
- const program = new Command().name("alchemy-x402").description("CLI for Alchemy x402 authentication and payments").version("0.1.0");
127
+ const { version } = createRequire(import.meta.url)("../../package.json");
128
+ const program = new Command().name("@alchemy/x402").description("CLI for Alchemy x402 authentication and payments").version(version);
127
129
  program.addCommand(signSiweCommand);
128
130
  program.addCommand(walletCommand);
129
131
  program.addCommand(payCommand);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/lib/siwe.ts","../src/lib/wallet.ts","../src/lib/payment.ts"],"mappings":";;;KAAY,GAAA;AAAA,UAEK,UAAA;EACf,UAAA,EAAY,GAAA;EACZ,OAAA,EAAS,GAAA;AAAA;AAAA,UAGM,eAAA;EACf,UAAA;EACA,YAAA;EACA,KAAA;EACA,QAAA;AAAA;AAAA,UAGe,oBAAA;EACf,UAAA;EACA,qBAAA;AAAA;;;iBCNoB,QAAA,CAAS,IAAA,EAAM,eAAA,GAAkB,OAAA;;;iBCWvC,cAAA,CAAA,GAAkB,UAAA;AAAA,iBAMlB,gBAAA,CAAiB,UAAA,WAAqB,GAAA;;;iBClBtC,eAAA,CAAgB,UAAA,WAAkB,UAAA;AAAA,iBA0B5B,aAAA,CAAc,IAAA,EAAM,oBAAA,GAAuB,OAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/lib/siwe.ts","../src/lib/wallet.ts","../src/lib/payment.ts"],"mappings":";;;KAAY,GAAA;AAAA,UAEK,UAAA;EACf,UAAA,EAAY,GAAA;EACZ,OAAA,EAAS,GAAA;AAAA;AAAA,UAGM,eAAA;EACf,UAAA;EACA,YAAA;EACA,KAAA;EACA,QAAA;AAAA;AAAA,UAGe,oBAAA;EACf,UAAA;EACA,qBAAA;AAAA;;;iBCNoB,QAAA,CAAS,IAAA,EAAM,eAAA,GAAkB,OAAA;;;iBCavC,cAAA,CAAA,GAAkB,UAAA;AAAA,iBAMlB,gBAAA,CAAiB,UAAA,WAAqB,GAAA;;;iBCjBtC,eAAA,CAAgB,UAAA,WAAkB,UAAA;AAAA,iBA8B5B,aAAA,CACpB,IAAA,EAAM,oBAAA,GACL,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/lib/siwe.ts","../src/lib/wallet.ts","../src/lib/payment.ts"],"mappings":";;;KAAY,GAAA;AAAA,UAEK,UAAA;EACf,UAAA,EAAY,GAAA;EACZ,OAAA,EAAS,GAAA;AAAA;AAAA,UAGM,eAAA;EACf,UAAA;EACA,YAAA;EACA,KAAA;EACA,QAAA;AAAA;AAAA,UAGe,oBAAA;EACf,UAAA;EACA,qBAAA;AAAA;;;iBCNoB,QAAA,CAAS,IAAA,EAAM,eAAA,GAAkB,OAAA;;;iBCWvC,cAAA,CAAA,GAAkB,UAAA;AAAA,iBAMlB,gBAAA,CAAiB,UAAA,WAAqB,GAAA;;;iBClBtC,eAAA,CAAgB,UAAA,WAAkB,UAAA;AAAA,iBA0B5B,aAAA,CAAc,IAAA,EAAM,oBAAA,GAAuB,OAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/lib/siwe.ts","../src/lib/wallet.ts","../src/lib/payment.ts"],"mappings":";;;KAAY,GAAA;AAAA,UAEK,UAAA;EACf,UAAA,EAAY,GAAA;EACZ,OAAA,EAAS,GAAA;AAAA;AAAA,UAGM,eAAA;EACf,UAAA;EACA,YAAA;EACA,KAAA;EACA,QAAA;AAAA;AAAA,UAGe,oBAAA;EACf,UAAA;EACA,qBAAA;AAAA;;;iBCNoB,QAAA,CAAS,IAAA,EAAM,eAAA,GAAkB,OAAA;;;iBCavC,cAAA,CAAA,GAAkB,UAAA;AAAA,iBAMlB,gBAAA,CAAiB,UAAA,WAAqB,GAAA;;;iBCjBtC,eAAA,CAAgB,UAAA,WAAkB,UAAA;AAAA,iBA8B5B,aAAA,CACpB,IAAA,EAAM,oBAAA,GACL,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/lib/wallet.ts","../src/lib/siwe.ts","../src/lib/payment.ts"],"sourcesContent":["import { readFileSync, existsSync } from \"fs\";\nimport { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\";\nimport type { Hex, WalletInfo } from \"../types.js\";\n\nconst RAW_HEX_RE = /^[0-9a-fA-F]{64}$/;\n\nexport function resolvePrivateKey(keyOrPath: string): string {\n if (keyOrPath.startsWith(\"0x\") || RAW_HEX_RE.test(keyOrPath)) {\n return keyOrPath;\n }\n if (existsSync(keyOrPath)) {\n return readFileSync(keyOrPath, \"utf-8\").trim();\n }\n return keyOrPath;\n}\n\nexport function normalizePrivateKey(key: string): Hex {\n const resolved = resolvePrivateKey(key);\n return resolved.startsWith(\"0x\") ? (resolved as Hex) : (`0x${resolved}` as Hex);\n}\n\nexport function generateWallet(): WalletInfo {\n const privateKey = generatePrivateKey();\n const account = privateKeyToAccount(privateKey);\n return { privateKey, address: account.address };\n}\n\nexport function getWalletAddress(privateKey: string): Hex {\n const normalized = normalizePrivateKey(privateKey);\n const account = privateKeyToAccount(normalized);\n return account.address;\n}\n","import { randomBytes } from \"crypto\";\nimport ms from \"ms\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport type { SignSiweOptions } from \"../types.js\";\nimport { normalizePrivateKey } from \"./wallet.js\";\n\nfunction generateNonce(): string {\n return randomBytes(16).toString(\"hex\");\n}\n\nexport async function signSiwe(opts: SignSiweOptions): Promise<string> {\n const normalized = normalizePrivateKey(opts.privateKey);\n const account = privateKeyToAccount(normalized);\n\n const issuedAt = opts.issuedAt ?? new Date().toISOString();\n const nonce = opts.nonce ?? generateNonce();\n\n const duration = ms((opts.expiresAfter ?? \"1h\") as Parameters<typeof ms>[0]);\n if (duration === undefined) {\n throw new Error(`Invalid duration: ${opts.expiresAfter}`);\n }\n const expirationTime = new Date(new Date(issuedAt).getTime() + duration).toISOString();\n\n const message = [\n \"x402.alchemy.com wants you to sign in with your Ethereum account:\",\n account.address,\n \"\",\n \"Sign in to Alchemy Gateway\",\n \"\",\n \"URI: https://x402.alchemy.com\",\n \"Version: 1\",\n \"Chain ID: 8453\",\n `Nonce: ${nonce}`,\n `Issued At: ${issuedAt}`,\n `Expiration Time: ${expirationTime}`,\n ].join(\"\\n\");\n\n const signature = await account.signMessage({ message });\n\n const encodedMessage = Buffer.from(message).toString(\"base64url\");\n return `${encodedMessage}.${signature}`;\n}\n","import { createPublicClient, http } from \"viem\";\nimport { base } from \"viem/chains\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { ExactEvmScheme, toClientEvmSigner } from \"@x402/evm\";\nimport { x402Client } from \"@x402/core/client\";\nimport { decodePaymentRequiredHeader, encodePaymentSignatureHeader } from \"@x402/core/http\";\nimport type { CreatePaymentOptions } from \"../types.js\";\nimport { normalizePrivateKey } from \"./wallet.js\";\n\nexport function buildX402Client(privateKey: string) {\n const normalized = normalizePrivateKey(privateKey);\n const account = privateKeyToAccount(normalized);\n\n const publicClient = createPublicClient({\n chain: base,\n transport: http(),\n });\n\n const signer = toClientEvmSigner({\n address: account.address,\n signTypedData: async (params) => {\n return account.signTypedData(params as Parameters<typeof account.signTypedData>[0]);\n },\n readContract: async (params) => {\n return publicClient.readContract(params as Parameters<typeof publicClient.readContract>[0]);\n },\n });\n\n const scheme = new ExactEvmScheme(signer);\n const client = new x402Client();\n client.register(\"eip155:8453\", scheme);\n client.register(\"eip155:84532\", scheme);\n return client;\n}\n\nexport async function createPayment(opts: CreatePaymentOptions): Promise<string> {\n const client = buildX402Client(opts.privateKey);\n const paymentRequired = decodePaymentRequiredHeader(opts.paymentRequiredHeader);\n const payload = await client.createPaymentPayload(paymentRequired);\n return encodePaymentSignatureHeader(payload);\n}\n"],"mappings":";;;;;;;;;;;AAIA,MAAM,aAAa;AAEnB,SAAgB,kBAAkB,WAA2B;AAC3D,KAAI,UAAU,WAAW,KAAK,IAAI,WAAW,KAAK,UAAU,CAC1D,QAAO;AAET,KAAI,WAAW,UAAU,CACvB,QAAO,aAAa,WAAW,QAAQ,CAAC,MAAM;AAEhD,QAAO;;AAGT,SAAgB,oBAAoB,KAAkB;CACpD,MAAM,WAAW,kBAAkB,IAAI;AACvC,QAAO,SAAS,WAAW,KAAK,GAAI,WAAoB,KAAK;;AAG/D,SAAgB,iBAA6B;CAC3C,MAAM,aAAa,oBAAoB;AAEvC,QAAO;EAAE;EAAY,SADL,oBAAoB,WAAW,CACT;EAAS;;AAGjD,SAAgB,iBAAiB,YAAyB;AAGxD,QADgB,oBADG,oBAAoB,WAAW,CACH,CAChC;;;;;ACxBjB,SAAS,gBAAwB;AAC/B,QAAO,YAAY,GAAG,CAAC,SAAS,MAAM;;AAGxC,eAAsB,SAAS,MAAwC;CAErE,MAAM,UAAU,oBADG,oBAAoB,KAAK,WAAW,CACR;CAE/C,MAAM,WAAW,KAAK,6BAAY,IAAI,MAAM,EAAC,aAAa;CAC1D,MAAM,QAAQ,KAAK,SAAS,eAAe;CAE3C,MAAM,WAAW,GAAI,KAAK,gBAAgB,KAAkC;AAC5E,KAAI,aAAa,OACf,OAAM,IAAI,MAAM,qBAAqB,KAAK,eAAe;CAE3D,MAAM,iBAAiB,IAAI,KAAK,IAAI,KAAK,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,aAAa;CAEtF,MAAM,UAAU;EACd;EACA,QAAQ;EACR;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;EACV,cAAc;EACd,oBAAoB;EACrB,CAAC,KAAK,KAAK;CAEZ,MAAM,YAAY,MAAM,QAAQ,YAAY,EAAE,SAAS,CAAC;AAGxD,QAAO,GADgB,OAAO,KAAK,QAAQ,CAAC,SAAS,YAAY,CACxC,GAAG;;;;;AC/B9B,SAAgB,gBAAgB,YAAoB;CAElD,MAAM,UAAU,oBADG,oBAAoB,WAAW,CACH;CAE/C,MAAM,eAAe,mBAAmB;EACtC,OAAO;EACP,WAAW,MAAM;EAClB,CAAC;CAYF,MAAM,SAAS,IAAI,eAVJ,kBAAkB;EAC/B,SAAS,QAAQ;EACjB,eAAe,OAAO,WAAW;AAC/B,UAAO,QAAQ,cAAc,OAAsD;;EAErF,cAAc,OAAO,WAAW;AAC9B,UAAO,aAAa,aAAa,OAA0D;;EAE9F,CAAC,CAEuC;CACzC,MAAM,SAAS,IAAI,YAAY;AAC/B,QAAO,SAAS,eAAe,OAAO;AACtC,QAAO,SAAS,gBAAgB,OAAO;AACvC,QAAO;;AAGT,eAAsB,cAAc,MAA6C;CAC/E,MAAM,SAAS,gBAAgB,KAAK,WAAW;CAC/C,MAAM,kBAAkB,4BAA4B,KAAK,sBAAsB;AAE/E,QAAO,6BADS,MAAM,OAAO,qBAAqB,gBAAgB,CACtB"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/lib/wallet.ts","../src/lib/siwe.ts","../src/lib/payment.ts"],"sourcesContent":["import { readFileSync, existsSync } from \"fs\";\nimport { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\";\nimport type { Hex, WalletInfo } from \"../types.js\";\n\nconst RAW_HEX_RE = /^[0-9a-fA-F]{64}$/;\n\nexport function resolvePrivateKey(keyOrPath: string): string {\n if (keyOrPath.startsWith(\"0x\") || RAW_HEX_RE.test(keyOrPath)) {\n return keyOrPath;\n }\n if (existsSync(keyOrPath)) {\n return readFileSync(keyOrPath, \"utf-8\").trim();\n }\n return keyOrPath;\n}\n\nexport function normalizePrivateKey(key: string): Hex {\n const resolved = resolvePrivateKey(key);\n return resolved.startsWith(\"0x\")\n ? (resolved as Hex)\n : (`0x${resolved}` as Hex);\n}\n\nexport function generateWallet(): WalletInfo {\n const privateKey = generatePrivateKey();\n const account = privateKeyToAccount(privateKey);\n return { privateKey, address: account.address };\n}\n\nexport function getWalletAddress(privateKey: string): Hex {\n const normalized = normalizePrivateKey(privateKey);\n const account = privateKeyToAccount(normalized);\n return account.address;\n}\n","import { randomBytes } from \"crypto\";\nimport ms from \"ms\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport type { SignSiweOptions } from \"../types.js\";\nimport { normalizePrivateKey } from \"./wallet.js\";\n\nfunction generateNonce(): string {\n return randomBytes(16).toString(\"hex\");\n}\n\nexport async function signSiwe(opts: SignSiweOptions): Promise<string> {\n const normalized = normalizePrivateKey(opts.privateKey);\n const account = privateKeyToAccount(normalized);\n\n const issuedAt = opts.issuedAt ?? new Date().toISOString();\n const nonce = opts.nonce ?? generateNonce();\n\n const duration = ms((opts.expiresAfter ?? \"1h\") as Parameters<typeof ms>[0]);\n if (duration === undefined) {\n throw new Error(`Invalid duration: ${opts.expiresAfter}`);\n }\n const expirationTime = new Date(\n new Date(issuedAt).getTime() + duration,\n ).toISOString();\n\n const message = [\n \"x402.alchemy.com wants you to sign in with your Ethereum account:\",\n account.address,\n \"\",\n \"Sign in to Alchemy Gateway\",\n \"\",\n \"URI: https://x402.alchemy.com\",\n \"Version: 1\",\n \"Chain ID: 8453\",\n `Nonce: ${nonce}`,\n `Issued At: ${issuedAt}`,\n `Expiration Time: ${expirationTime}`,\n ].join(\"\\n\");\n\n const signature = await account.signMessage({ message });\n\n const encodedMessage = Buffer.from(message).toString(\"base64url\");\n return `${encodedMessage}.${signature}`;\n}\n","import { createPublicClient, http } from \"viem\";\nimport { base } from \"viem/chains\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { ExactEvmScheme, toClientEvmSigner } from \"@x402/evm\";\nimport { x402Client } from \"@x402/core/client\";\nimport {\n decodePaymentRequiredHeader,\n encodePaymentSignatureHeader,\n} from \"@x402/core/http\";\nimport type { CreatePaymentOptions } from \"../types.js\";\nimport { normalizePrivateKey } from \"./wallet.js\";\n\nexport function buildX402Client(privateKey: string) {\n const normalized = normalizePrivateKey(privateKey);\n const account = privateKeyToAccount(normalized);\n\n const publicClient = createPublicClient({\n chain: base,\n transport: http(),\n });\n\n const signer = toClientEvmSigner({\n address: account.address,\n signTypedData: async (params) => {\n return account.signTypedData(\n params as Parameters<typeof account.signTypedData>[0],\n );\n },\n readContract: async (params) => {\n return publicClient.readContract(\n params as Parameters<typeof publicClient.readContract>[0],\n );\n },\n });\n\n const scheme = new ExactEvmScheme(signer);\n const client = new x402Client();\n client.register(\"eip155:8453\", scheme);\n client.register(\"eip155:84532\", scheme);\n return client;\n}\n\nexport async function createPayment(\n opts: CreatePaymentOptions,\n): Promise<string> {\n const client = buildX402Client(opts.privateKey);\n const paymentRequired = decodePaymentRequiredHeader(\n opts.paymentRequiredHeader,\n );\n const payload = await client.createPaymentPayload(paymentRequired);\n return encodePaymentSignatureHeader(payload);\n}\n"],"mappings":";;;;;;;;;;;AAIA,MAAM,aAAa;AAEnB,SAAgB,kBAAkB,WAA2B;AAC3D,KAAI,UAAU,WAAW,KAAK,IAAI,WAAW,KAAK,UAAU,CAC1D,QAAO;AAET,KAAI,WAAW,UAAU,CACvB,QAAO,aAAa,WAAW,QAAQ,CAAC,MAAM;AAEhD,QAAO;;AAGT,SAAgB,oBAAoB,KAAkB;CACpD,MAAM,WAAW,kBAAkB,IAAI;AACvC,QAAO,SAAS,WAAW,KAAK,GAC3B,WACA,KAAK;;AAGZ,SAAgB,iBAA6B;CAC3C,MAAM,aAAa,oBAAoB;AAEvC,QAAO;EAAE;EAAY,SADL,oBAAoB,WAAW,CACT;EAAS;;AAGjD,SAAgB,iBAAiB,YAAyB;AAGxD,QADgB,oBADG,oBAAoB,WAAW,CACH,CAChC;;;;;AC1BjB,SAAS,gBAAwB;AAC/B,QAAO,YAAY,GAAG,CAAC,SAAS,MAAM;;AAGxC,eAAsB,SAAS,MAAwC;CAErE,MAAM,UAAU,oBADG,oBAAoB,KAAK,WAAW,CACR;CAE/C,MAAM,WAAW,KAAK,6BAAY,IAAI,MAAM,EAAC,aAAa;CAC1D,MAAM,QAAQ,KAAK,SAAS,eAAe;CAE3C,MAAM,WAAW,GAAI,KAAK,gBAAgB,KAAkC;AAC5E,KAAI,aAAa,OACf,OAAM,IAAI,MAAM,qBAAqB,KAAK,eAAe;CAE3D,MAAM,iBAAiB,IAAI,KACzB,IAAI,KAAK,SAAS,CAAC,SAAS,GAAG,SAChC,CAAC,aAAa;CAEf,MAAM,UAAU;EACd;EACA,QAAQ;EACR;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;EACV,cAAc;EACd,oBAAoB;EACrB,CAAC,KAAK,KAAK;CAEZ,MAAM,YAAY,MAAM,QAAQ,YAAY,EAAE,SAAS,CAAC;AAGxD,QAAO,GADgB,OAAO,KAAK,QAAQ,CAAC,SAAS,YAAY,CACxC,GAAG;;;;;AC9B9B,SAAgB,gBAAgB,YAAoB;CAElD,MAAM,UAAU,oBADG,oBAAoB,WAAW,CACH;CAE/C,MAAM,eAAe,mBAAmB;EACtC,OAAO;EACP,WAAW,MAAM;EAClB,CAAC;CAgBF,MAAM,SAAS,IAAI,eAdJ,kBAAkB;EAC/B,SAAS,QAAQ;EACjB,eAAe,OAAO,WAAW;AAC/B,UAAO,QAAQ,cACb,OACD;;EAEH,cAAc,OAAO,WAAW;AAC9B,UAAO,aAAa,aAClB,OACD;;EAEJ,CAAC,CAEuC;CACzC,MAAM,SAAS,IAAI,YAAY;AAC/B,QAAO,SAAS,eAAe,OAAO;AACtC,QAAO,SAAS,gBAAgB,OAAO;AACvC,QAAO;;AAGT,eAAsB,cACpB,MACiB;CACjB,MAAM,SAAS,gBAAgB,KAAK,WAAW;CAC/C,MAAM,kBAAkB,4BACtB,KAAK,sBACN;AAED,QAAO,6BADS,MAAM,OAAO,qBAAqB,gBAAgB,CACtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alchemy/x402",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "CLI and library for Alchemy x402 authentication and payments",
5
5
  "type": "module",
6
6
  "exports": {
@@ -18,6 +18,10 @@
18
18
  "bin": {
19
19
  "alchemy-x402": "./dist/cli/index.mjs"
20
20
  },
21
+ "lint-staged": {
22
+ "*.{js,ts,mjs,mts,cjs,cts}": "eslint --fix",
23
+ "*.{json,md,yml,yaml}": "prettier --write"
24
+ },
21
25
  "dependencies": {
22
26
  "@commander-js/extra-typings": "^14.0.0",
23
27
  "@x402/core": "^2.4.0",
@@ -30,10 +34,17 @@
30
34
  "devDependencies": {
31
35
  "@changesets/changelog-github": "^0.5.2",
32
36
  "@changesets/cli": "^2.29.8",
37
+ "@eslint/js": "^10.0.1",
33
38
  "@types/ms": "^2.1.0",
34
39
  "@types/node": "^25.3.0",
40
+ "eslint": "^10.0.2",
41
+ "eslint-config-prettier": "^10.1.8",
42
+ "eslint-plugin-prettier": "^5.5.5",
43
+ "lint-staged": "^16.2.7",
44
+ "prettier": "^3.8.1",
35
45
  "tsdown": "^0.20.3",
36
46
  "typescript": "^5.9.3",
47
+ "typescript-eslint": "^8.56.1",
37
48
  "vitest": "^4.0.18"
38
49
  },
39
50
  "files": [
@@ -50,6 +61,8 @@
50
61
  "build": "tsdown",
51
62
  "typecheck": "tsc --noEmit",
52
63
  "test": "vitest run",
64
+ "lint": "eslint . && prettier --check .",
65
+ "lint:fix": "eslint . --fix && prettier --write .",
53
66
  "changeset": "changeset",
54
67
  "version-packages": "changeset version",
55
68
  "release": "pnpm run build && changeset publish"