Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 48 additions & 6 deletions .github/workflows/generate-tokenlists.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,20 @@ jobs:
runs-on: ubuntu-latest

permissions:
# Give the default GITHUB_TOKEN write permission to commit and push the
# added or changed files to the repository.
contents: write
id-token: write

steps:
- name: Checkout code
uses: actions/checkout@v5
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.10"

- name: Install uv
uses: astral-sh/setup-uv@v4
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4.2.0
with:
enable-cache: true

Expand All @@ -37,7 +36,50 @@ jobs:

# Commit all changed files back to the repository
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
uses: stefanzweifel/git-auto-commit-action@b863ae1933cb653a53c021fe36dbb774e1fb9403 # v5.2.0
with:
commit_message: "Update tokenlist-mainnet.json"
file_pattern: "tokenlist-mainnet.json"

# ---- npm package build & publish ----

- name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "20"
registry-url: "https://registry.npmjs.org"

- name: Install npm dependencies
working-directory: npm
run: npm ci --ignore-scripts

- name: Audit dependencies
working-directory: npm
run: npm audit --audit-level=high

- name: Build package
working-directory: npm
run: npm run build

- name: Validate package contents
working-directory: npm
run: npm pack --dry-run 2>&1

- name: Check if version already published
id: check
working-directory: npm
run: |
VERSION=$(node -p "require('./package.json').version")
CURRENT=$(npm view @monad-crypto/token-list version 2>/dev/null || echo "0.0.0")
if [ "$CURRENT" = "$VERSION" ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi

- name: Publish to npm
if: steps.check.outputs.skip != 'true'
working-directory: npm
run: npm publish --access public --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
.env
.DS_Store

# npm package build artifacts
npm/src/mainnet.ts
npm/src/testnet.ts
npm/src/index.ts
npm/dist/
npm/node_modules/
30 changes: 30 additions & 0 deletions npm/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

91 changes: 91 additions & 0 deletions npm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
{
"name": "@monad-crypto/token-list",
"version": "2.27.0",
"description": "Official Monad token list with full TypeScript types",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/monad-crypto/token-list.git",
"directory": "npm"
},
"homepage": "https://github.com/monad-crypto/token-list/tree/main/npm#readme",
"bugs": {
"url": "https://github.com/monad-crypto/token-list/issues"
},
"keywords": [
"monad",
"token-list",
"erc20",
"crypto",
"ethereum"
],
"type": "module",
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"types": "./dist/esm/index.d.ts",
"exports": {
".": {
"import": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
},
"require": {
"types": "./dist/cjs/index.d.ts",
"default": "./dist/cjs/index.js"
}
},
"./mainnet": {
"import": {
"types": "./dist/esm/mainnet.d.ts",
"default": "./dist/esm/mainnet.js"
},
"require": {
"types": "./dist/cjs/mainnet.d.ts",
"default": "./dist/cjs/mainnet.js"
}
},
"./testnet": {
"import": {
"types": "./dist/esm/testnet.d.ts",
"default": "./dist/esm/testnet.js"
},
"require": {
"types": "./dist/cjs/testnet.d.ts",
"default": "./dist/cjs/testnet.js"
}
},
"./types": {
"import": {
"types": "./dist/esm/types.d.ts",
"default": "./dist/esm/types.js"
},
"require": {
"types": "./dist/cjs/types.d.ts",
"default": "./dist/cjs/types.js"
}
},
"./package.json": "./package.json"
},
"files": [
"dist"
],
"scripts": {
"clean": "rm -rf dist",
"codegen": "node scripts/codegen.mjs",
"build:esm": "tsc -p tsconfig.json",
"build:cjs": "tsc -p tsconfig.cjs.json",
"build": "npm run clean && npm run codegen && npm run build:esm && npm run build:cjs",
"prepublishOnly": "npm run build"
},
"devDependencies": {
"typescript": "~5.7.0"
},
"sideEffects": false,
"engines": {
"node": ">=18"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org"
}
}
130 changes: 130 additions & 0 deletions npm/scripts/codegen.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#!/usr/bin/env node

/**
* Codegen script: reads the generated token list JSON files and produces
* TypeScript source files that embed the data with full type information.
*/

import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = join(__dirname, "..", "..");
const SRC = join(__dirname, "..", "src");
const CJS_DIR = join(__dirname, "..", "dist", "cjs");

mkdirSync(SRC, { recursive: true });
mkdirSync(CJS_DIR, { recursive: true });

// Generate mainnet.ts

const mainnetJson = readFileSync(
join(ROOT, "tokenlist-mainnet.json"),
"utf-8",
);

let mainnetData;
try {
mainnetData = JSON.parse(mainnetJson);
} catch (err) {
console.error("codegen: tokenlist-mainnet.json is not valid JSON:", err.message);
process.exit(1);
}

writeFileSync(
join(SRC, "mainnet.ts"),
[
"// Auto-generated by codegen.mjs -- do not edit",
'import type { MainnetTokenList } from "./types.js";',
"",
`export const mainnetTokenList = ${mainnetJson.trimEnd()} as const satisfies MainnetTokenList;`,
"",
].join("\n"),
);

// Generate testnet.ts

const testnetJson = readFileSync(
join(ROOT, "tokenlist-testnet.json"),
"utf-8",
);

try {
JSON.parse(testnetJson);
} catch (err) {
console.error("codegen: tokenlist-testnet.json is not valid JSON:", err.message);
process.exit(1);
}

writeFileSync(
join(SRC, "testnet.ts"),
[
"// Auto-generated by codegen.mjs -- do not edit",
'import type { TestnetTokenList } from "./types.js";',
"",
`export const testnetTokenList = ${testnetJson.trimEnd()} as const satisfies TestnetTokenList;`,
"",
].join("\n"),
);

// Generate index.ts (barrel re-export)

writeFileSync(
join(SRC, "index.ts"),
[
"// Auto-generated by codegen.mjs -- do not edit",
'export { mainnetTokenList } from "./mainnet.js";',
'export { testnetTokenList } from "./testnet.js";',
"export type {",
" Address,",
" MonadMainnetChainId,",
" MonadTestnetChainId,",
" MonadChainId,",
" CrossChainId,",
" BridgeProtocol,",
" CrossChainAddressEntry,",
" CrossChainAddresses,",
" BridgeInfo,",
" TokenExtensions,",
" Token,",
" MainnetToken,",
" TestnetToken,",
" Version,",
" TokenList,",
" MainnetTokenList,",
" TestnetTokenList,",
'} from "./types.js";',
"",
].join("\n"),
);

// Generate dist/cjs/package.json (CommonJS marker)

writeFileSync(
join(CJS_DIR, "package.json"),
`${JSON.stringify({ type: "commonjs" }, null, 2)}\n`,
);

// Sync package.json and package-lock.json versions from the token list

const NPM_DIR = join(__dirname, "..");
const { major, minor, patch } = mainnetData.version;
const version = `${major}.${minor}.${patch}`;

const pkgPath = join(NPM_DIR, "package.json");
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
pkg.version = version;
writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);

const lockPath = join(NPM_DIR, "package-lock.json");
const lock = JSON.parse(readFileSync(lockPath, "utf-8"));
lock.version = version;
if (lock.packages?.[""]) {
lock.packages[""].version = version;
}
writeFileSync(lockPath, `${JSON.stringify(lock, null, 2)}\n`);

console.log(
`codegen: wrote src/mainnet.ts, src/testnet.ts, src/index.ts, dist/cjs/package.json, package.json (v${version}), package-lock.json (v${version})`,
);
Loading
Loading