@perspectivefi/addresses 0.0.0-stage → 0.1.1

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.
@@ -0,0 +1,55 @@
1
+ 'use strict'
2
+ /**
3
+ * ESLint flat-config preset for @perspectivefi/addresses. Plain JS, no eslint dependency.
4
+ *
5
+ * ESLint keeps only ONE `no-restricted-syntax` setting per file, so everything is combined
6
+ * into one rule entry. If you already use `no-restricted-syntax`, merge `restrictedSyntax`
7
+ * into your own list instead of spreading the preset.
8
+ */
9
+
10
+ const MESSAGE = 'Contract addresses come from @perspectivefi/addresses (see ADDRESS_REGISTRY spec)'
11
+
12
+ // Zero address is allowed; every other 0x + 40 hex string is an error.
13
+ const EVM = '/^0x(?!0{40}$)[0-9a-fA-F]{40}$/'
14
+ const STELLAR = '/^C[A-Z2-7]{55}$/'
15
+
16
+ /** Error on string literals and template chunks that look like a contract address. */
17
+ const hardcodedAddressRules = [
18
+ { selector: `Literal[value=${EVM}]`, message: MESSAGE },
19
+ { selector: `Literal[value=${STELLAR}]`, message: MESSAGE },
20
+ { selector: `TemplateElement[value.cooked=${EVM}]`, message: MESSAGE },
21
+ { selector: `TemplateElement[value.cooked=${STELLAR}]`, message: MESSAGE },
22
+ ]
23
+
24
+ const CALLEE = '/^(address|requireAddress)$/'
25
+ const CALL_MESSAGE =
26
+ 'The 2nd argument of address()/requireAddress() must be a string literal so the key can be checked statically.'
27
+
28
+ /** Error when address()/requireAddress() gets a non-literal key (also matches `ns.address(...)`). */
29
+ const literalKeyRules = [
30
+ {
31
+ selector: `CallExpression[callee.name=${CALLEE}][arguments.length>=2][arguments.1.type!="Literal"]`,
32
+ message: CALL_MESSAGE,
33
+ },
34
+ {
35
+ selector: `CallExpression[callee.property.name=${CALLEE}][arguments.length>=2][arguments.1.type!="Literal"]`,
36
+ message: CALL_MESSAGE,
37
+ },
38
+ ]
39
+
40
+ const restrictedSyntax = [...hardcodedAddressRules, ...literalKeyRules]
41
+
42
+ const config = {
43
+ name: '@perspectivefi/addresses',
44
+ rules: {
45
+ 'no-restricted-syntax': ['error', ...restrictedSyntax],
46
+ },
47
+ }
48
+
49
+ // Helpers are non-enumerable so spreading / passing `config` to ESLint never sees unknown keys.
50
+ const helpers = { default: config, restrictedSyntax, hardcodedAddressRules, literalKeyRules }
51
+ for (const [name, value] of Object.entries(helpers)) {
52
+ Object.defineProperty(config, name, { value, enumerable: false })
53
+ }
54
+
55
+ module.exports = config
@@ -0,0 +1,21 @@
1
+ export interface RestrictedSyntaxRule {
2
+ selector: string
3
+ message: string
4
+ }
5
+
6
+ export interface AddressesEslintConfig {
7
+ name: string
8
+ rules: { 'no-restricted-syntax': ['error', ...RestrictedSyntaxRule[]] }
9
+ }
10
+
11
+ declare const config: AddressesEslintConfig & {
12
+ default: AddressesEslintConfig
13
+ /** All selectors, to merge into an existing `no-restricted-syntax` list. */
14
+ restrictedSyntax: RestrictedSyntaxRule[]
15
+ /** Only the hardcoded-address selectors. */
16
+ hardcodedAddressRules: RestrictedSyntaxRule[]
17
+ /** Only the "2nd argument must be a literal" selectors. */
18
+ literalKeyRules: RestrictedSyntaxRule[]
19
+ }
20
+
21
+ export default config
package/package.json CHANGED
@@ -1,6 +1,83 @@
1
1
  {
2
- "name": "@perspectivefi/addresses",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "@perspectivefi/addresses",
3
+ "version": "0.1.1",
4
+ "description": "Contract address registry for Spectra: one list of every address, each with a status. Prod only accepts `safe`.",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "sideEffects": false,
9
+ "engines": {
10
+ "node": ">=18"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "import": {
15
+ "types": "./dist/index.d.mts",
16
+ "default": "./dist/index.mjs"
17
+ },
18
+ "require": {
19
+ "types": "./dist/index.d.ts",
20
+ "default": "./dist/index.js"
21
+ }
22
+ },
23
+ "./prod": {
24
+ "import": {
25
+ "types": "./dist/prod.d.mts",
26
+ "default": "./dist/prod.mjs"
27
+ },
28
+ "require": {
29
+ "types": "./dist/prod.d.ts",
30
+ "default": "./dist/prod.js"
31
+ }
32
+ },
33
+ "./eslint": {
34
+ "types": "./eslint/index.d.ts",
35
+ "default": "./eslint/index.cjs"
36
+ },
37
+ "./registry.json": "./dist/registry.json",
38
+ "./package.json": "./package.json"
39
+ },
40
+ "bin": {
41
+ "spectra-addresses": "./dist/cli.js"
42
+ },
43
+ "files": [
44
+ "dist",
45
+ "eslint"
46
+ ],
47
+ "publishConfig": {
48
+ "access": "public"
49
+ },
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/perspectivefi/spectra-addresses.git"
53
+ },
54
+ "keywords": [
55
+ "spectra",
56
+ "addresses",
57
+ "registry",
58
+ "contracts"
59
+ ],
60
+ "author": "Spectra",
61
+ "license": "ISC",
62
+ "scripts": {
63
+ "generate": "tsx scripts/generate.ts",
64
+ "build": "npm run generate && rm -rf dist && tsup && tsx scripts/emit-registry.ts",
65
+ "typecheck": "npm run generate && tsc --noEmit",
66
+ "test": "npm run generate && npm run build && vitest run",
67
+ "validate": "tsx scripts/validate.ts",
68
+ "onchain": "tsx scripts/onchain.ts",
69
+ "format": "prettier --write .",
70
+ "format:check": "prettier --check ."
71
+ },
72
+ "devDependencies": {
73
+ "@types/node": "^26.6.4",
74
+ "esbuild": "^0.28.2",
75
+ "eslint": "^10.12.0",
76
+ "prettier": "^3.9.9",
77
+ "tsup": "^8.5.1",
78
+ "tsx": "^4.23.15",
79
+ "typescript": "^5.9.3",
80
+ "viem": "^2.57.4",
81
+ "vitest": "^5.0.3"
82
+ }
83
+ }