@qorechain/sdk 0.6.1 → 0.7.0

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.
package/README.md CHANGED
@@ -377,6 +377,83 @@ const params = await client.crossvm.params();
377
377
  const status = await client.qor.getCrossVmMessage("42");
378
378
  ```
379
379
 
380
+ ## Authenticator lanes (v0.7.0 / chain v3.1.85)
381
+
382
+ A linked external key — a Phantom **ed25519** key, or a MetaMask **secp256k1**
383
+ key bound **by address** — can spend from the ONE canonical PQC account through
384
+ a **relayer** that submits the tx and pays the fee (its own hybrid-PQC signature
385
+ satisfies the ante). The external key **never produces an ML-DSA co-signature**;
386
+ its signature over the domain-separated, replay-bound sign-bytes **is** the
387
+ authorization. Every lane runs under least-privilege, spending-limit and
388
+ revocable terms enforced on-chain.
389
+
390
+ Three messages carry the lanes:
391
+
392
+ | Message | Type URL | Composer |
393
+ |---|---|---|
394
+ | `MsgExecuteEVM` | `/qorechain.abstractaccount.v1.MsgExecuteEVM` | `msg.abstractaccount.executeEvm` |
395
+ | `MsgExecuteCosmos` | `/qorechain.abstractaccount.v1.MsgExecuteCosmos` | `msg.abstractaccount.executeCosmos` |
396
+ | `MsgRotatePQCKey` | `/qorechain.pqc.v1.MsgRotatePQCKey` | `msg.pqc.rotatePqcKey` |
397
+
398
+ **Sign-bytes helpers** rebuild the exact digest the chain re-derives, so you can
399
+ verify byte-for-byte before signing: `evmAuthSignBytes` / `cosmosAuthSignBytes`
400
+ (32-byte SHA-256 digests) and `rotationSignBytes` (the domain-separated string
401
+ both keys sign).
402
+
403
+ **NONCE semantics:**
404
+
405
+ - `MsgExecuteEVM.nonce` = the account's **current EVM nonce** (the relayer is a
406
+ different account than the owner, so its envelope does **not** bump the
407
+ account's nonce — pass the value as-is, do **not** `+1`).
408
+ - `MsgExecuteCosmos.nonce` = the **per-authenticator sequence** for
409
+ `(account, pubkey)`, a store counter distinct from the account's own sequence.
410
+
411
+ **Wallet builders** sign the digest and return a ready-to-broadcast message:
412
+ `buildPhantomExecuteEvm` / `buildPhantomExecuteCosmos` (ed25519),
413
+ `buildMetaMaskExecuteEvm` / `buildMetaMaskExecuteCosmos` (secp256k1-by-address),
414
+ and `registerEthAuthenticatorMsg` to link an EVM key first.
415
+
416
+ **Permission taxonomy & errors.** Query the on-chain permission schema with
417
+ `client.query.getPermissionSchema()` (REST) / `client.grpc.permissionSchema()`
418
+ (gRPC) and compare a candidate action against it before submitting. Failed lanes
419
+ surface structured codes via `decodeTxError` — codespace `abstractaccount`: `5`
420
+ SpendingLimitExceeded, `6` SessionKeyExpired, `10` PermissionDenied, `11`
421
+ AuthenticatorReplay; codespace `pqc`: `21` HybridVerifyFailed.
422
+
423
+ **Key rotation.** Migrate a legacy `shake256(mnemonic)` key to the canonical,
424
+ address-bound key with `rotatePqcKeyMsgFromMnemonic` (dual-signs over
425
+ `rotationSignBytes`); `derivePqcLegacy` re-derives the old key for the old-key
426
+ half of the signature.
427
+
428
+ ```ts
429
+ import {
430
+ buildPhantomExecuteEvm,
431
+ rotatePqcKeyMsgFromMnemonic,
432
+ } from "@qorechain/sdk";
433
+
434
+ // Phantom ed25519 authenticator spends from the canonical account; the relayer
435
+ // broadcasts and pays. `nonce` is the account's CURRENT EVM nonce (no +1).
436
+ const execMsg = await buildPhantomExecuteEvm({
437
+ wallet, // { publicKey, signMessage }
438
+ relayer: "qor1relayer…",
439
+ chainId: "qorechain-diana",
440
+ account: "qor1canonical…",
441
+ to: "0xRecipient…",
442
+ value: "1000000000000000000", // 1 QOR in aqor (wei)
443
+ nonce: await client.qor.getTransactionCount("0xAccount…"),
444
+ });
445
+
446
+ // One-shot: migrate a legacy shake256(mnemonic) key to the address-bound key.
447
+ const { msg: rotateMsg } = rotatePqcKeyMsgFromMnemonic({
448
+ account: "qor1canonical…",
449
+ mnemonic,
450
+ chainId: "qorechain-diana",
451
+ });
452
+ ```
453
+
454
+ See the [Authenticators guide](../../docs/docs/guides/authenticators.md) for the
455
+ full lifecycle (register → spend → rotate → revoke).
456
+
380
457
  ## Network reference
381
458
 
382
459
  - Mainnet chain id: `qorechain-vladi` (live).