Wharf 4.0.1

In Wharf 4.0.1, every @wharfkit package shares one version number, so installing any one of them brings the matching versions of the rest. The release also brings session keys to @wharfkit/session, the API changes developed as @wharfkit/antelope 2.0, and a signing reliability fix for Anchor on iOS.

Package names on npm are unchanged, and every package is developed in github.com/wharfkit/js.

Upgrading

Set every @wharfkit entry in your package.json to ^4.0.1, whatever version it was on before, and reinstall from a clean lockfile:

{
  "dependencies": {
    "@wharfkit/antelope": "^4.0.1",
    "@wharfkit/session": "^4.0.1",
    "@wharfkit/wallet-plugin-anchor": "^4.0.1",
    "@wharfkit/web-renderer": "^4.0.1"
  }
}

Packages in the release depend on each other by exact version, and none declares another as a peer dependency. Remove any @wharfkit entry you added only to satisfy a peer warning, and any resolutions or overrides entry that pins a @wharfkit package, since either can bring back a second copy of a package.

Every package requires Node.js 20.19.0 or later, and both of its bundles are compiled to ES2020. webpack 4 and browsers released before March 2020 cannot parse that level; to support them, transpile @wharfkit packages in your build. Projects that must stay on an older Node.js version can stay on @wharfkit/antelope@1.

After reinstalling, confirm that your project resolves one copy of antelope with npm ls @wharfkit/antelope (or yarn why, pnpm why). The expected result is one entry at 4.0.1. @wharfkit/apiclient-leap, -telos and -wax are outside the release and depend on an older antelope, so a project using one of them resolves a second copy.

Changes to check in your code

  • K1 signatures differ byte for byte from the ones 1.x produced for the same key and message. They are valid and canonical, and older signatures still verify. Re-record any test that asserts a literal signature string.
  • PrivateKey.sharedSecret() returns the full 32 bytes of the shared x-coordinate, where 1.x stripped leading zero bytes. Pass {legacy: true} for the stripped form: privateKey.sharedSecret(publicKey, {legacy: true}).
  • A binary extension field (T$) absent from the data is left out of the object or Struct instance antelope decodes, matching nodeos, where 1.x set it to null. An empty optional field (T?) still decodes as null. Code that tests a decoded extension field for null tests for undefined: decoded.field === null becomes decoded.field === undefined.
  • Float32.toString() returns the shortest round-tripping string, so 1.5 renders as "1.5" in place of "1.5000000". Infinity, NaN and negative zero render as nodeos spells them.
  • SessionKit.restore() takes a PartialSerializedSession, and the RestoreArgs type is removed. Only an explicit import type {RestoreArgs} needs editing.
  • SessionKit.persistSession() takes options in place of a boolean: persistSession(session, false) becomes persistSession(session, {setAsDefault: false}).
  • Namespaces re-exported from CommonJS dependencies by @wharfkit/cli, @wharfkit/protocol-esr and @wharfkit/session are no longer frozen with a null prototype in the CommonJS bundles. Only code that checks one with instanceof, Object.getPrototypeOf or Object.isFrozen sees a difference.
  • pako moved to 3.x inside antelope. It is ESM with no default export, which matters only to a project that imports pako itself.

What is new

Session keys

Your application can hold a key that signs a chosen set of actions on its own, such as the moves in a game, and send everything else to the user’s wallet. Configure the actions on the SessionKit, then ask the user to approve the key:

const sessionKit = new SessionKit(args, {
  sessionKey: {
    whitelist: [{ contract: "mygame", actions: ["move", "attack"] }],
  },
})

await session.setupSessionKey()

setupSessionKey() generates the key, adds it under a permission named after your application, and links the listed actions to it, in one transaction the user approves. Session also has methods to check, update and remove the key. Session keys need a UserInterface that draws four prompts (consent, an existing key on the permission, a whitelist mismatch, and removal); @wharfkit/web-renderer draws all four.

The key signs the listed actions without showing them to the user, and every action outside the whitelist goes to the wallet for approval.

Waiting for irreversibility

Set awaitIrreversible on transact(), or once on the SessionKit, and the call resolves only after the transaction is irreversible:

await session.transact({ action }, { awaitIrreversible: true })

const sessionKit = new SessionKit(args, { awaitIrreversible: true })

broadcastOptions sets returnFailureTrace, retryTrx and retryTrxNumBlocks directly:

await session.transact(
  { action },
  { broadcastOptions: { retryTrx: true, retryTrxNumBlocks: 10 } }
)

Anchor signing on iOS

Signing with Anchor on the same iOS device completes when Safari brings the user back in a fresh tab, a case where @wharfkit/wallet-plugin-anchor could lose the signature before.

Smaller changes

  • @wharfkit/antelope uses @noble/curves and @noble/hashes in place of elliptic, contributed by grctest.
  • Authority.sort() orders keys, accounts and waits the way nodeos does, so the chain accepts the updateauth you build with it. Name, PermissionLevel and PublicKey gained compare().
  • FetchProvider uses the fetch built into Node.js and browsers, so you can drop node-fetch.
  • get_table_rows queries float64 and float128 secondary indexes.
  • SessionKit keeps stored sessions intact: login(), restore() and persistSession() resolve after the session is in storage, so two logins in a row keep both sessions; logout(session) clears the stored default only when that session was the default; restoreAll() leaves storage untouched; and each restored session gets its own wallet plugin instance.
  • @wharfkit/roborovski gains activity(), which pages through an account’s history with next() and prev() and filters by contract, action and date range.
  • @wharfkit/web-renderer accepts colorMode, "light" or "dark".
  • @wharfkit/protocol-scatter and the four wallet plugins built on it import cleanly under Node.js.
  • @wharfkit/account-creation-plugin-metamask no longer brings a second copy of antelope.
  • @wharfkit/bundle ships @wharfkit/web-ui in place of @wharfkit/web-renderer, adds @wharfkit/token and @wharfkit/roborovski, and its ES module build is one file that imports correctly.
  • @wharfkit/atomicassets reads the AtomicMarket v2 royalty endpoints and the marketplace stats endpoint, reports the media-type descriptors on schema fields and the live collection fee on auctions, buyoffers and template buyoffers, and percent-encodes the path segments you pass it, contributed by robrigo.
  • @wharfkit/contract sends a scope bound of zero to the chain.
  • Every package is licensed under BSD-3-Clause. @wharfkit/signing-request was previously MIT.

New packages

@wharfkit/light-api is a client for the Light API service, contributed by includenull.

@wharfkit/wallet-plugin-tacklebox adds the TackleBox wallet, contributed by on-a-t-break.