Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
761233d
docs: add branching guide (#191)
MuncleUscles Jun 11, 2026
7679ea0
fix(fees)!: move wildcard callKey sentinel to keccak256(empty), deplo…
MuncleUscles Jun 11, 2026
60e8ca3
feat(sdk): developer-NFT read/claim actions + nonce coercion fix (#195)
MuncleUscles Jul 7, 2026
6f691ce
feat: vesting delegator actions + ABI (#193)
MuncleUscles Jul 7, 2026
a338ad5
feat: epoch-zero SDK helpers (getCurrentEpoch, isValidatorBelowMinSta…
MuncleUscles Jul 7, 2026
666d115
chore: untrack vitest-generated tsconfig.vitest-temp.json (#196)
MuncleUscles Jul 8, 2026
289839d
fix: make git install build script self contained (#197)
MuncleUscles Jul 8, 2026
5788928
fix: build package during git prepare (#198)
MuncleUscles Jul 8, 2026
bf42f13
feat(staking,vesting,accounts): provider-lane writes + native transfe…
MuncleUscles Jul 10, 2026
50a936c
feat(calldata)!: move method-call key from "method" to "" (empty stri…
MuncleUscles Jul 23, 2026
0b7e3bd
fix: resolve triggered transaction IDs from decision receipts (#202)
MuncleUscles Jul 26, 2026
6f12738
fix: support proof-bearing validator joins (#206)
MuncleUscles Aug 9, 2026
7666f0b
Revert "fix: support proof-bearing validator joins (#206)" (#207)
MuncleUscles Aug 11, 2026
bae1eee
feat: proof-bearing validator joins (restores #206, gated on its 4 co…
MuncleUscles Aug 18, 2026
d7d3262
fix: align SDK consumers with the resolution-kernel train (#212)
kirilaa Aug 31, 2026
b79622d
fix(fees): add exact quote and decision parity (#214)
MuncleUscles Sep 2, 2026
facd9e9
feat(release): add Studio dev preview channel (#217)
MuncleUscles Sep 3, 2026
672631b
Release v2.0.0-rc.1 [skip ci]
MuncleUscles Sep 3, 2026
8c899cc
fix(release): keep tag publish workflows active (#218)
MuncleUscles Sep 3, 2026
6ee12f8
fix(consumers): align staking and lifecycle reads with the v0.6 produ…
cgmello Sep 23, 2026
4dabdf2
fix(fees): price receipt floor with wrapper and terminal reserve (#223)
MuncleUscles Sep 28, 2026
642f27c
fix: type GenVM min gas schema metadata
maho0638 Oct 2, 2026
74bbdc3
test: cover min gas contract schema fields
maho0638 Oct 2, 2026
d0e89d0
test: cover optional min gas schema fields
maho0638 Oct 2, 2026
cae5e54
ci: independently validate upstream PR 226 exact source
maho0638 Oct 12, 2026
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
23 changes: 23 additions & 0 deletions .github/workflows/diag-pr226-20261012.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Verify PR 226 latest source
on:
push:
branches: [diag/validate-pr226-20261012]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
exact-source-build-tests:
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run build
- run: npx vitest run --typecheck
29 changes: 21 additions & 8 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,23 @@ jobs:

- run: npm ci

- name: Verify tag matches package.json version
- name: Verify tag and resolve npm dist-tag
id: version
run: |
TAG_VERSION="${GITHUB_REF_NAME#v}"
PKG_VERSION="$(node -p "require('./package.json').version")"
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
echo "Tag ($TAG_VERSION) and package.json ($PKG_VERSION) disagree — refusing to publish." >&2
echo "Re-cut the release via scripts/release.sh so the tag and the committed version match." >&2
if [ "${GITHUB_REF_TYPE:-}" != "tag" ]; then
echo "Publish must run from a git tag. Current ref type: ${GITHUB_REF_TYPE:-unknown}" >&2
exit 1
fi

TAG_VERSION="${GITHUB_REF_NAME#v}"
PKG_VERSION="$(node -p "require('./package.json').version")"
node scripts/resolve-release-channel.mjs "$TAG_VERSION" "$PKG_VERSION" >> "$GITHUB_OUTPUT"
echo "Tag $GITHUB_REF_NAME matches package.json $PKG_VERSION."

- run: npm run build

- name: Publish to npm
run: npm publish --provenance --access public
run: npm publish --provenance --access public --tag "${{ steps.version.outputs.npm_dist_tag }}"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Expand All @@ -63,6 +65,17 @@ jobs:
if [ -z "$NOTES" ]; then
NOTES="Release $GITHUB_REF_NAME"
fi

NOTES="$NOTES

npm install genlayer-js@${{ steps.version.outputs.npm_dist_tag }}"

RELEASE_FLAGS=()
if [ "${{ steps.version.outputs.is_prerelease }}" = "true" ]; then
RELEASE_FLAGS+=(--prerelease)
fi

gh release create "$GITHUB_REF_NAME" \
--title "$GITHUB_REF_NAME" \
--notes "$NOTES"
--notes "$NOTES" \
"${RELEASE_FLAGS[@]}"
4 changes: 4 additions & 0 deletions .github/workflows/smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ on:
jobs:
smoke:
name: Testnet Smoke Tests
# The v2 line intentionally targets the resolution-kernel train and does
# not support the currently deployed pre-train testnets. Its live coverage
# comes from the cross-repository E2E stack until those testnets upgrade.
if: github.event_name != 'pull_request' || github.base_ref != 'v2-dev'
runs-on: ubuntu-latest
timeout-minutes: 5
continue-on-error: true
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ node_modules
.env
.DS_Store
dist
coverage
coverage
tsconfig.vitest-temp*.json
4 changes: 3 additions & 1 deletion .release-it.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@

module.exports = {
git: {
commitMessage: "Release v${version} [skip ci]",
// Keep release commits CI-active: GitHub also suppresses tag-triggered
// workflows when the tagged commit contains a skip directive.
commitMessage: "Release v${version}",
tagName: "v${version}",
requireCleanWorkingDir: false,
requireUpstream: false,
Expand Down
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,46 @@


## [2.0.0-rc.1](https://github.com/genlayerlabs/genlayer-js/compare/v1.1.6...v2.0.0-rc.1) (2026-09-03)


### ⚠ BREAKING CHANGES

* **calldata:** method-call calldata now uses the "" key instead of
"method". Encoded bytes for every write/read/view/schema call change. Peers
must run the v0.6 genvm-manager (or a node/studio build that expects the ""
key).
* **fees:** move wildcard callKey sentinel to keccak256(empty), deploy key = bytes32(0) (#190)
* **fees:** estimation correctness, wait-for-decided semantics, v0.6 enum completeness (#187)

### Features

* **calldata:** move method-call key from "method" to "" (empty string) ([#192](https://github.com/genlayerlabs/genlayer-js/issues/192)) ([50a936c](https://github.com/genlayerlabs/genlayer-js/commit/50a936c4f0e436739851c8a4c47badcdd8c588dd))
* epoch-zero SDK helpers (getCurrentEpoch, isValidatorBelowMinStake) ([#194](https://github.com/genlayerlabs/genlayer-js/issues/194)) ([a338ad5](https://github.com/genlayerlabs/genlayer-js/commit/a338ad5646b4b53cb2df418a25dbef20a8cb5f11))
* **fees:** estimation correctness, wait-for-decided semantics, v0.6 enum completeness ([#187](https://github.com/genlayerlabs/genlayer-js/issues/187)) ([2af6928](https://github.com/genlayerlabs/genlayer-js/commit/2af6928e2587091fb33f5f703160c8a160606048))
* **fees:** integrate v0.6 tooling ([#180](https://github.com/genlayerlabs/genlayer-js/issues/180)) ([75f90e2](https://github.com/genlayerlabs/genlayer-js/commit/75f90e2c47297416b7273b0fa3967e207c4c3a6f)), closes [#168](https://github.com/genlayerlabs/genlayer-js/issues/168) [genlayer-testing-suite#78](https://github.com/genlayerlabs/genlayer-testing-suite/issues/78) [genlayer-cli#297](https://github.com/genlayerlabs/genlayer-cli/issues/297) [#170](https://github.com/genlayerlabs/genlayer-js/issues/170) [#168](https://github.com/genlayerlabs/genlayer-js/issues/168) [#172](https://github.com/genlayerlabs/genlayer-js/issues/172) [#173](https://github.com/genlayerlabs/genlayer-js/issues/173) [#174](https://github.com/genlayerlabs/genlayer-js/issues/174) [#175](https://github.com/genlayerlabs/genlayer-js/issues/175) [#176](https://github.com/genlayerlabs/genlayer-js/issues/176) [#177](https://github.com/genlayerlabs/genlayer-js/issues/177)
* proof-bearing validator joins (restores [#206](https://github.com/genlayerlabs/genlayer-js/issues/206), gated on its 4 companions) ([#208](https://github.com/genlayerlabs/genlayer-js/issues/208)) ([bae1eee](https://github.com/genlayerlabs/genlayer-js/commit/bae1eeeccedf0572047c59fc3d271794f83c4176)), closes [#207](https://github.com/genlayerlabs/genlayer-js/issues/207) [#1290](https://github.com/genlayerlabs/genlayer-js/issues/1290)
* **release:** add Studio dev preview channel ([#217](https://github.com/genlayerlabs/genlayer-js/issues/217)) ([facd9e9](https://github.com/genlayerlabs/genlayer-js/commit/facd9e9dc9a289d0110fe3b5b1a14a2938fe6e01))
* **sdk:** developer-NFT read/claim actions + nonce coercion fix ([#195](https://github.com/genlayerlabs/genlayer-js/issues/195)) ([60e8ca3](https://github.com/genlayerlabs/genlayer-js/commit/60e8ca3c253baa66f62e570ee4b4fdbd50cfa447))
* **staking,vesting,accounts:** provider-lane writes + native transfer ([#200](https://github.com/genlayerlabs/genlayer-js/issues/200)) ([bf42f13](https://github.com/genlayerlabs/genlayer-js/commit/bf42f13a66a2bb762e5ef1065eb89789b9c45d4a))
* vesting delegator actions + ABI ([#193](https://github.com/genlayerlabs/genlayer-js/issues/193)) ([6f691ce](https://github.com/genlayerlabs/genlayer-js/commit/6f691ce704092992216dce83e54447dbdeb8c3b2)), closes [#1154](https://github.com/genlayerlabs/genlayer-js/issues/1154)


### Bug Fixes

* align SDK consumers with the resolution-kernel train ([#212](https://github.com/genlayerlabs/genlayer-js/issues/212)) ([d7d3262](https://github.com/genlayerlabs/genlayer-js/commit/d7d32627e036cf57600558a099bb589ccc5c8d2a))
* build package during git prepare ([#198](https://github.com/genlayerlabs/genlayer-js/issues/198)) ([5788928](https://github.com/genlayerlabs/genlayer-js/commit/57889281db1e34df49abcf6129ffe6f347e4de4d))
* **fees:** add exact quote and decision parity ([#214](https://github.com/genlayerlabs/genlayer-js/issues/214)) ([b79622d](https://github.com/genlayerlabs/genlayer-js/commit/b79622d3ce79ffd6e579c1d1ec1f68fe13cc8ac1))
* **fees:** move wildcard callKey sentinel to keccak256(empty), deploy key = bytes32(0) ([#190](https://github.com/genlayerlabs/genlayer-js/issues/190)) ([7679ea0](https://github.com/genlayerlabs/genlayer-js/commit/7679ea064f6a3e8348b485d5b76013791c6fbd6e))
* include execution budget floor in fee defaults ([#186](https://github.com/genlayerlabs/genlayer-js/issues/186)) ([02eeabc](https://github.com/genlayerlabs/genlayer-js/commit/02eeabc9765de3768724a18f7c4fd9c1db0bb667))
* make git install build script self contained ([#197](https://github.com/genlayerlabs/genlayer-js/issues/197)) ([289839d](https://github.com/genlayerlabs/genlayer-js/commit/289839d13183013eac050e052999d45d392e09e0))
* resolve triggered transaction IDs from decision receipts ([#202](https://github.com/genlayerlabs/genlayer-js/issues/202)) ([0b7e3bd](https://github.com/genlayerlabs/genlayer-js/commit/0b7e3bd63aeab25beaf63c14956af6a458f56b06))
* support proof-bearing validator joins ([#206](https://github.com/genlayerlabs/genlayer-js/issues/206)) ([6f12738](https://github.com/genlayerlabs/genlayer-js/commit/6f1273885567ff5cda77b7459edfd6666c5859d0))


### Reverts

* Revert "fix: support proof-bearing validator joins (#206)" (#207) ([7666f0b](https://github.com/genlayerlabs/genlayer-js/commit/7666f0b73987aa75b7fcd1d62c2759364ce36824)), closes [#206](https://github.com/genlayerlabs/genlayer-js/issues/206) [#207](https://github.com/genlayerlabs/genlayer-js/issues/207)

## 1.1.8 (2026-05-06)


Expand Down
20 changes: 6 additions & 14 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,11 @@ Have ideas for new features or use cases? We're eager to hear them! But first:

## Branch model

This repo uses a branch-per-major release model. There is no `main`.

- **`v1`** — current stable major. PRs for bug fixes / non-breaking features target this branch. Releases are cut from here (see `scripts/release.sh`).
- **`v<next>-dev`** — when a major bump is in progress (e.g. `v2-dev`), this branch is open for the new major's work. PRs introducing breaking changes target this branch, not `v1`.
- **Older majors** (`v0`, etc.) stay on the repo for back-ports and security patches. Default branch on github.com is whichever major is current stable.

When you fork or clone, the default branch is `v1` today. If you have a `main` branch from a previous checkout, delete it locally:

```sh
git checkout v1
git branch -D main
git remote prune origin
```
See [docs/BRANCHING.md](docs/BRANCHING.md) for the current release-train model.
In short: independently releasable work may target the stable branch directly;
multi-feature or cross-repo train work uses the active `*-dev` integration
branch and is promoted to the matching stable branch when ready. `main` is only
the default/static GitHub branch.

## Releases

Expand Down Expand Up @@ -106,4 +98,4 @@ Connect with the GenLayer community to discuss, collaborate, and share insights:
- **[Discord Channel](https://discord.gg/8Jm4v89VAu)**: Our primary hub for discussions, support, and announcements.
- **[Telegram Group](https://t.me/genlayer)**: For more informal chats and quick updates.

Your continuous feedback drives better product development. Please engage with us regularly to test, discuss, and improve the GenLayerJS SDK.
Your continuous feedback drives better product development. Please engage with us regularly to test, discuss, and improve the GenLayerJS SDK.
50 changes: 42 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ values in wallet or app UI before signing.
const estimate = await client.estimateTransactionFees({
leaderTimeunitsAllocation: 100n,
validatorTimeunitsAllocation: 200n,
rotations: [0n],
});

const txHash = await client.writeContract({
Expand All @@ -132,6 +131,10 @@ const txHash = await client.writeContract({
});
```

When `rotations` is omitted from an estimate, the SDK funds every round through
the chain's `defaultConsensusMaxRotations`. Pass `rotations` explicitly—including
`[0n]`—when the transaction should use a lower rotation budget.

If `fees.distribution` is provided without `feeValue`, the SDK derives the fee
deposit from FeeManager on network backends, or from `sim_getFeeConfig` on
Studio. Use `messageAllocations` with `estimateTransactionFees` for transactions
Expand Down Expand Up @@ -267,11 +270,10 @@ transaction hash; on Studio/localnet it is the target GenLayer transaction id.
A transaction can be finalized by consensus but still have a failed execution. Always check `txExecutionResult` before reading contract state:

```typescript
import { ExecutionResult, TransactionStatus } from "genlayer-js/types";
import { ExecutionResult } from "genlayer-js/types";

const receipt = await client.waitForTransactionReceipt({
const receipt = await client.waitForFinalization({
hash: txHash,
status: TransactionStatus.FINALIZED,
});

if (receipt.txExecutionResultName === ExecutionResult.FINISHED_WITH_RETURN) {
Expand All @@ -297,6 +299,27 @@ Transactions can emit messages to other contracts. These messages create new chi
```typescript
const tx = await client.getTransaction({ hash: txHash });

// The default model is derived from the exact stored state. Processing entries
// have a phase; decided entries have an outcome.
console.log(tx.lifecycle);
// {state: "processing", phase: "revealing"}
// {state: "decided", outcome: "accepted"}

// Advanced protocol consumers can explicitly request timestamp projection and
// the exact resolution action/source. Current Studio can prove only the stored
// status, so unsupported action/decision fields remain inactive there.
const protocolLifecycle = await client.advanced.getTransactionLifecycle({ hash: txHash });
console.log(protocolLifecycle.storedStatus);
console.log(protocolLifecycle.projectedStatus);
console.log(protocolLifecycle.resolutionSource);
if (protocolLifecycle.resolutionAction === "Finalize") {
// Finalize is the protocol's current action/capability, not a transaction status.
}

// The train retains the authoritative execution hash, not the old receipt
// bytes. `txReceipt` is therefore unavailable on train transactions.
console.log(tx.txExecutionHash);

// Messages emitted by the contract during execution
console.log(tx.messages);
// [{messageType, recipient, value, data, onAcceptance, saltNonce}, ...]
Expand Down Expand Up @@ -393,7 +416,7 @@ const txHash = await client.writeContract({
});
```

Available networks: `"localnet"`, `"studionet"`, `"testnetAsimov"`, `"testnetBradbury"`.
Available networks: `"localnet"`, `"studionet"`, `"studioDevnet"`, `"testnetAsimov"`, `"testnetBradbury"`.

> **Note:** If the wallet is on the wrong chain when you call `writeContract`, the SDK will throw a clear error telling you which chain the wallet is on vs. which chain the client expects. Call `client.connect()` to resolve this.

Expand Down Expand Up @@ -428,17 +451,24 @@ const epochInfo = await client.getEpochInfo();
// totalClaimed: "500 GEN", // Total claimed rewards
// }

// Get active validators
// Get validators currently eligible for consensus duties
const validators = await client.getActiveValidators();

// Inspect every identity in the append-only joined registry
const joinedValidators = await client.getJoinedValidators();

// Check if address is a validator
const isValidator = await client.isValidator("0x...");

// Get validator info
const validatorInfo = await client.getValidatorInfo("0x...");

// Join as validator (requires account with funds)
const result = await client.validatorJoin({ amount: "42000gen" });
// Join as validator (requires an owner account with funds and the operator key)
const registration = await createOperatorRegistration({
privateKey: operatorPrivateKey,
...(await client.getValidatorRegistrationContext()),
});
const result = await client.validatorJoin({ amount: "42000gen", registration });

// Join as delegator
const delegateResult = await client.delegatorJoin({
Expand Down Expand Up @@ -470,3 +500,7 @@ We welcome contributions to GenLayerJS SDK! Whether it's new features, improved
## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

### v0.6 consumer migration

See [the v2 migration guide](docs/consumer-migration-v06.md) for the staking rewards rename, producer ABI changes, execution generation, and package selection.
58 changes: 58 additions & 0 deletions docs/BRANCHING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Branching and Release Trains

This repo follows the GenLayer release-train model.

## Current Train

- Current stable branch: `v1`
- Active integration branch: `v2-dev`
- Next stable target: `v2`
- `main`: default/static branch alias for the active integration branch

## Stable Branches

Stable branches are long-lived release lines. They are named after the version
line they ship, for example `v1` or `v2`.

PRs may target a stable branch directly when the merged result should be
releasable immediately. This is appropriate for bug fixes, small non-breaking
features, isolated release fixes, or a breaking change that is intentionally
shipping as the next version by itself.

Stable branches must remain releasable. PRs into stable branches are expected to
pass the required cross-repo `E2E Tests` gate before merge.

## Integration Branches

Integration branches are optional. Use one when multiple changes need to
accumulate before release, especially for cross-repo work, dependent features,
breaking changes that must ship together, or a train that needs advisory E2E
while still expected to be red.

Integration branches are named after the target stable branch plus `-dev`, for
example `v2-dev`. Feature PRs for that train target the integration branch.

PRs into integration branches may run `E2E Tests` as advisory checks. They are
not the release gate.

## Promotion and Release

When an integration train is ready, open a promotion PR from the integration
branch to the matching stable branch, for example `v2-dev` to `v2`.

That promotion PR is the release-readiness gate and must pass required
cross-repo `E2E Tests`. The actual package release is cut from the stable branch
using a version tag after the stable branch is ready.

## `main`

`main` exists for GitHub UX and tools that require a stable default branch. It is
not a release branch and it is not the integration target.

This repo keeps `main` forwarded to the active integration branch using
automation. PRs opened against `main` are automatically retargeted to the branch
listed in `support/ci/ACTIVE_DEV_BRANCH`.

When changing the active integration branch, update
`support/ci/ACTIVE_DEV_BRANCH`, the repo docs, and the corresponding
`genlayer-e2e` release-train matrix in the same change set.
Loading
Loading