Skip to content
Merged
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
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install
node-version: 24
cache: npm
- run: npm ci
- run: npm run typecheck
- run: npm run build
- run: npm run test
- run: npm run pack:check
149 changes: 149 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
name: Publish packages to npm

on:
push:
branches:
- "v*"
- "v*-dev"
tags:
- "v*.*.*"

permissions:
contents: write
id-token: write

jobs:
credentials:
name: Verify npm publishing credentials
if: startsWith(github.ref, 'refs/heads/')
runs-on: ubuntu-latest
environment: Publish
steps:
- uses: actions/setup-node@v4
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
- name: Require and validate the repository-owned npm token
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
if [ -z "$NODE_AUTH_TOKEN" ]; then
echo "NPM_TOKEN is not available to the Publish environment." >&2
exit 1
fi
npm whoami

publish:
name: Publish coordinated package set
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
environment: Publish
concurrency:
group: npm-${{ github.ref }}
cancel-in-progress: false
steps:
- name: Checkout tag
uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-node@v4
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
cache: npm

- name: Require repository-owned npm credentials
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
if [ -z "$NODE_AUTH_TOKEN" ]; then
echo "NPM_TOKEN is not available to the Publish environment." >&2
exit 1
fi
npm whoami

- name: Verify tag, package set, and owning branch
run: |
version="${GITHUB_REF_NAME#v}"
release_json="$(node scripts/check-release.mjs --version "$version" --tag "$GITHUB_REF_NAME")"
branch="$(node -e 'console.log(JSON.parse(process.argv[1]).branch)' "$release_json")"
git fetch origin "refs/heads/$branch:refs/remotes/origin/$branch"
if [ "$(git rev-parse HEAD)" != "$(git rev-parse "origin/$branch")" ]; then
echo "$GITHUB_REF_NAME is not the current head of $branch; refusing to publish." >&2
exit 1
fi

- run: npm ci
- run: npm run typecheck
- run: npm run build
- run: npm test
- run: npm run pack:check

- name: Verify upstream and existing package provenance
run: |
version="${GITHUB_REF_NAME#v}"
required_js="$(node -e "import('./scripts/release-policy.mjs').then(m => console.log(m.requiredGenlayerJsVersion))")"
test "$(npm view "genlayer-js@$required_js" version)" = "$required_js"
for package_name in \
@genlayer/transaction-kit \
@genlayer/transaction-kit-react \
@genlayer/transaction-kit-vue; do
if npm view "$package_name@$version" version >/dev/null 2>&1; then
published_sha="$(npm view "$package_name@$version" gitHead)"
if [ "$published_sha" != "$GITHUB_SHA" ]; then
echo "$package_name@$version already exists from $published_sha, not $GITHUB_SHA." >&2
exit 1
fi
echo "$package_name@$version already exists from this release commit; it can be resumed safely."
fi
done

- name: Publish all packages
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
version="${GITHUB_REF_NAME#v}"
dist_tag="$(node -e "import('./scripts/release-policy.mjs').then(m => console.log(m.parseReleaseVersion(process.argv[1]).distTag))" "$version")"
for workspace in packages/core packages/react packages/vue; do
package_name="$(node -p "require('./$workspace/package.json').name")"
if [ "$(npm view "$package_name@$version" gitHead 2>/dev/null || true)" = "$GITHUB_SHA" ]; then
echo "$package_name@$version was already published from this release commit; skipping."
continue
fi
npm publish --workspace "$workspace" --tag "$dist_tag" --provenance --access public
done

- name: Verify registry artifacts
run: |
version="${GITHUB_REF_NAME#v}"
for package_name in \
@genlayer/transaction-kit \
@genlayer/transaction-kit-react \
@genlayer/transaction-kit-vue; do
for attempt in 1 2 3 4 5 6; do
published="$(npm view "$package_name@$version" version 2>/dev/null || true)"
if [ "$published" = "$version" ]; then
break
fi
if [ "$attempt" -eq 6 ]; then
echo "$package_name@$version was not visible after publication." >&2
exit 1
fi
sleep 5
done
done

- name: Create GitHub prerelease
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
prerelease=()
if [[ "$GITHUB_REF_NAME" == *-* ]]; then
prerelease+=(--prerelease)
fi
gh release create "$GITHUB_REF_NAME" \
--verify-tag \
--title "$GITHUB_REF_NAME" \
--generate-notes \
"${prerelease[@]}"
35 changes: 20 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ verification layer, never a requirement.

| Package | What it is |
| --- | --- |
| [`@genlayer/transaction-kit`](packages/core) | Framework-agnostic core: `estimate` → `PolicyQuote`, `submit` (direct route via the injected wallet), `track` to decided/finalized, `verification` fee-config hash. Built on genlayer-js v2. |
| [`@genlayer/transaction-kit`](packages/core) | Framework-agnostic core: `estimate` → `PolicyQuote`, `submit` (direct route via the injected wallet), `track` to decided/finalized, `cancel`, `topUp`, `verification` fee-config hash. Built on genlayer-js v2. |
| [`@genlayer/transaction-kit-react`](packages/react) | `<GenLayerTransactionPanel />` + headless `useTransactionFlow` |
| [`@genlayer/transaction-kit-vue`](packages/vue) | Vue 3 equivalents |

Expand All @@ -19,24 +19,17 @@ Stage-1 scope: **direct submission only**. EIP-712 intents, the gateway contract
ERC-7730 clear-signing metadata are stage 2 (see the wallet architecture doc in
`genlayer-wallet`).

## Installing before the npm release
## Installation

npm `github:` dependencies can't reach monorepo subpackages, so each package is also
published as a packed orphan branch (`npm pack` output, dist included):
The first public release is available on the `rc` channel and is paired with
`genlayer-js@2.0.0-rc.1`:

```jsonc
{
"dependencies": {
"@genlayer/transaction-kit": "github:genlayerlabs/genlayer-transaction-kit#pkg/core",
"@genlayer/transaction-kit-react": "github:genlayerlabs/genlayer-transaction-kit#pkg/react",
"@genlayer/transaction-kit-vue": "github:genlayerlabs/genlayer-transaction-kit#pkg/vue"
}
}
```bash
npm install @genlayer/transaction-kit@rc
npm install @genlayer/transaction-kit-react@rc # React applications
npm install @genlayer/transaction-kit-vue@rc # Vue applications
```

These branches are refreshed manually on release-worthy changes and go away once the
packages are on npm.

## Quick start (React)

```tsx
Expand All @@ -58,6 +51,18 @@ const kit = createTransactionKit({ chain: testnetAsimov, provider: window.ethere
The adapters never import the core at runtime — the kit instance is injected and typed
structurally, so the packages version independently.

## Core API

| API | Purpose |
| --- | --- |
| `createTransactionKit({ chain, provider, account?, suggestions?, allowUnverified? })` | Creates a framework-agnostic kit around genlayer-js v2. Set `allowUnverified: true` only when you want adapters to allow signing despite a fee-policy hash mismatch. |
| `kit.estimate(input, tx?) -> Promise<PolicyQuote>` | Builds a fee quote from live prices plus optional developer fee suggestions. `PolicyQuote.verification` is `{ status: 'verified' \| 'mismatch' \| 'unavailable', expectedHash?, actualHash? }`; React/Vue block approval on `mismatch` unless `allowUnverified` is enabled, and warn without blocking on `unavailable`. |
| `kit.submit(quote, tx)` | Submits the direct deploy/write route through the injected wallet and returns `{ genlayerTxId, evmTxHash? }`. |
| `kit.track(genlayerTxId, onUpdate, { until? })` | Polls transaction state through decided/finalized and reports queue position while pending. |
| `kit.cancel({ hash })` | Wraps genlayer-js `cancelTransaction({ hash })` for pending Studio/localnet transactions. |
| `kit.topUp({ account?, txId, distribution, value })` | Wraps genlayer-js `topUpFees(...)` to deposit additional fee budget for an existing transaction. |
| `kit.verification(quote, tx)` | Returns the existing deterministic fee-config hash and summary used by panels and optional Snap verification. |

## Wallet compatibility (MetaMask, Privy, WalletConnect, …)

The kit depends only on an injected [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193)
Expand Down
Loading
Loading