@qorechain/sdk 0.5.0 → 0.5.2
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 +180 -10
- package/dist/index.cjs +12 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -20
- package/dist/index.d.ts +42 -20
- package/dist/index.js +12 -11
- package/dist/index.js.map +1 -1
- package/package.json +6 -9
package/README.md
CHANGED
|
@@ -17,7 +17,16 @@ network — a quantum-safe, triple-VM Layer 1 with native, EVM, and SVM accounts
|
|
|
17
17
|
- **NFT helpers** — ERC-721 / ERC-1155 wrappers in `@qorechain/evm`.
|
|
18
18
|
- **CosmWasm lifecycle** — query, upload, instantiate/instantiate2, execute,
|
|
19
19
|
migrate, and admin management.
|
|
20
|
-
- **PQC** — ML-DSA-87 (Dilithium-5) signing and hybrid-signature transactions
|
|
20
|
+
- **PQC** — ML-DSA-87 (Dilithium-5) signing and hybrid-signature transactions,
|
|
21
|
+
plus quantum-safe DX helpers (`ensurePqcRegistered` / `migrateToHybrid`).
|
|
22
|
+
- **Sidechains, paychains & rollups** — high-level `createMultilayerClient` and
|
|
23
|
+
`createRollupClient` helpers (v0.4.0).
|
|
24
|
+
- **Unified cross-VM calls** — `createCrossVMClient` with atomic triple-VM
|
|
25
|
+
transactions over `MsgCrossVMCall` (v0.5.0).
|
|
26
|
+
- **AI pre-flight** — on-chain risk/anomaly scoring (`simulateWithRiskScore`)
|
|
27
|
+
over the EVM precompiles before you sign (v0.5.0).
|
|
28
|
+
- **React kit** — hooks + connect kit in
|
|
29
|
+
[`@qorechain/react`](../react/README.md).
|
|
21
30
|
|
|
22
31
|
## Install
|
|
23
32
|
|
|
@@ -40,9 +49,9 @@ const client = createClient(); // testnet, localhost defaults
|
|
|
40
49
|
|
|
41
50
|
const remote = createClient({
|
|
42
51
|
endpoints: {
|
|
43
|
-
rest: "https://
|
|
44
|
-
rpc: "https://rpc
|
|
45
|
-
evmRpc: "https://evm
|
|
52
|
+
rest: "https://api-testnet.qore.host", // Cosmos REST (LCD)
|
|
53
|
+
rpc: "https://rpc-testnet.qore.host", // consensus RPC (for signing)
|
|
54
|
+
evmRpc: "https://evm-testnet.qore.host", // EVM + qor_ JSON-RPC
|
|
46
55
|
},
|
|
47
56
|
});
|
|
48
57
|
```
|
|
@@ -133,19 +142,180 @@ const info = await getContractInfo(cw, "qor1contract...");
|
|
|
133
142
|
const state = await queryContractSmart(cw, "qor1contract...", { get_count: {} });
|
|
134
143
|
|
|
135
144
|
// Writes
|
|
136
|
-
const signing = await connectCosmWasmSigner("https://rpc
|
|
145
|
+
const signing = await connectCosmWasmSigner("https://rpc-testnet.qore.host", signer);
|
|
137
146
|
const inst = await instantiate(signing, sender, codeId, { count: 0 }, "my-contract", {
|
|
138
147
|
fee: "auto",
|
|
139
148
|
});
|
|
140
149
|
await execute(signing, sender, inst.contractAddress, { increment: {} }, "auto");
|
|
141
150
|
```
|
|
142
151
|
|
|
143
|
-
###
|
|
152
|
+
### Sidechains, paychains & rollups (v0.4.0)
|
|
144
153
|
|
|
145
|
-
QoreChain
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
154
|
+
QoreChain's multilayer module lets a dApp register and operate its own
|
|
155
|
+
sidechains/paychains, and the rollup development kit (`rdk`) provides an
|
|
156
|
+
optimistic rollup lifecycle. Two high-level, strongly-typed helpers wrap the
|
|
157
|
+
typed message composers and query clients so you never hand-build protobuf `Any`
|
|
158
|
+
payloads. Both bind to a connected `TxClient`; pass a typed query client (from
|
|
159
|
+
`connectQueryClients`) for the reads.
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
import {
|
|
163
|
+
createClient,
|
|
164
|
+
createMultilayerClient,
|
|
165
|
+
createRollupClient,
|
|
166
|
+
connectQueryClients,
|
|
167
|
+
} from "@qorechain/sdk";
|
|
168
|
+
|
|
169
|
+
const client = createClient({ endpoints });
|
|
170
|
+
const tx = await client.connectTx(signer);
|
|
171
|
+
const query = await connectQueryClients("https://grpc.example");
|
|
172
|
+
|
|
173
|
+
// --- Multilayer: register → anchor → route ---
|
|
174
|
+
const ml = createMultilayerClient(tx, { query });
|
|
175
|
+
await ml.registerSidechain({ layerId: "game-l2", description: "game sidechain" });
|
|
176
|
+
await ml.registerPaychain({ layerId: "pay-l2", description: "payments paychain" });
|
|
177
|
+
await ml.anchorState({ layerId: "game-l2", layerHeight: 100n, stateRoot, validatorSetHash });
|
|
178
|
+
await ml.routeTransaction({ transactionPayload, preferredLayer: "game-l2" });
|
|
179
|
+
// Reads
|
|
180
|
+
const layer = await ml.getLayer("game-l2");
|
|
181
|
+
const layers = await ml.listLayers();
|
|
182
|
+
const stats = await ml.getRoutingStats();
|
|
183
|
+
|
|
184
|
+
// --- Rollups: create → submitBatch → executeWithdrawal ---
|
|
185
|
+
const rollup = createRollupClient(tx, { query, qor: client.qor });
|
|
186
|
+
await rollup.createRollup({ rollupId: "r1", profile: "default", vmType: "evm" });
|
|
187
|
+
await rollup.submitBatch({ rollupId: "r1", batchIndex: 0n, stateRoot, txCount: 12n });
|
|
188
|
+
await rollup.executeWithdrawal({ rollupId: "r1", batchIndex: 0n, withdrawalIndex: 0n, recipient, denom: "uqor", amount: 100n, proof });
|
|
189
|
+
// Reads (typed gRPC + qor_ conveniences)
|
|
190
|
+
const r = await rollup.getRollup("r1");
|
|
191
|
+
const batch = await rollup.getLatestBatch("r1");
|
|
192
|
+
const rollupStatus = await rollup.getRollupStatus("r1");
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Every write also has a `*Msg(...)` variant (`registerSidechainMsg`,
|
|
196
|
+
`submitBatchMsg`, …) that returns an `EncodeObject` for batching with other
|
|
197
|
+
messages. The challenge game (`challengeBatch` / `resolveChallenge`) and lifecycle
|
|
198
|
+
controls are exposed on the rollup client too.
|
|
199
|
+
|
|
200
|
+
You can also reach the typed query clients directly — `connectQueryClients`
|
|
201
|
+
returns `multilayer`, `rdk`, `bridge`, and `crossvm` clients (among others):
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
const layers = await query.multilayer.layers({});
|
|
205
|
+
const rollups = await query.rdk.rollups({});
|
|
206
|
+
const bridgeChains = await query.bridge.chainConfigs({});
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
See the [multilayer](../../docs/docs/guides/multilayer.md) and
|
|
210
|
+
[rollups](../../docs/docs/guides/rollups.md) guides.
|
|
211
|
+
|
|
212
|
+
### AI pre-flight risk scoring (v0.5.0)
|
|
213
|
+
|
|
214
|
+
QoreChain exposes an on-chain AI risk/anomaly model to any dApp through plain
|
|
215
|
+
`eth_call`s, so you can get an advisory verdict on a transaction **before** it is
|
|
216
|
+
signed or broadcast. The helpers live in `@qorechain/evm` (which owns viem) and
|
|
217
|
+
are re-exported from `@qorechain/sdk` for discovery — install `@qorechain/evm`
|
|
218
|
+
and `viem` (an optional peer) to use them.
|
|
219
|
+
|
|
220
|
+
`simulateWithRiskScore` bundles a gas estimate, a risk score from the
|
|
221
|
+
`aiRiskScore` precompile (`0x…0B01`), and an anomaly check from the
|
|
222
|
+
`aiAnomalyCheck` precompile (`0x…0B02`) into one `PreflightResult`:
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
import { simulateWithRiskScore, aiRiskScore, aiAnomalyCheck } from "@qorechain/sdk";
|
|
226
|
+
import { createPublicClient, http } from "viem";
|
|
227
|
+
|
|
228
|
+
const evm = createPublicClient({ transport: http("https://evm.example") });
|
|
229
|
+
|
|
230
|
+
const verdict = await simulateWithRiskScore(evm, {
|
|
231
|
+
from: "0xSender",
|
|
232
|
+
to: "0xContract",
|
|
233
|
+
data: "0x…", // calldata
|
|
234
|
+
value: 0n,
|
|
235
|
+
});
|
|
236
|
+
if (!verdict.safe) throw new Error("AI pre-flight flagged this transaction");
|
|
237
|
+
|
|
238
|
+
// Or call the precompiles individually:
|
|
239
|
+
const risk = await aiRiskScore(evm, "0xCalldata"); // { score, level }
|
|
240
|
+
const anomaly = await aiAnomalyCheck(evm, "0xSender", 1_000_000n); // { anomalyScore, flagged }
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
See the [AI pre-flight](../../docs/docs/guides/ai-preflight.md) guide.
|
|
244
|
+
|
|
245
|
+
### Unified cross-VM calls (v0.5.0)
|
|
246
|
+
|
|
247
|
+
QoreChain routes calls across its EVM, CosmWasm, and SVM execution environments
|
|
248
|
+
over a single `MsgCrossVMCall`. `createCrossVMClient` builds, signs, and
|
|
249
|
+
broadcasts these for you — including `callAtomic`, which packs several calls into
|
|
250
|
+
**one** transaction so a triple-VM workflow settles atomically.
|
|
251
|
+
|
|
252
|
+
This SDK encodes the payload per VM: an `{ evm: { abi, functionName, args } }`
|
|
253
|
+
payload is ABI-encoded with viem's `encodeFunctionData`, a `{ cosmwasm: {...} }`
|
|
254
|
+
payload is `JSON.stringify`'d to UTF-8, and a raw `{ payload }` is sent as-is.
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
import { createCrossVMClient, connectQueryClients } from "@qorechain/sdk";
|
|
258
|
+
|
|
259
|
+
const query = await connectQueryClients("https://grpc.example");
|
|
260
|
+
const xvm = createCrossVMClient(tx, { query });
|
|
261
|
+
|
|
262
|
+
// Single call into a CosmWasm contract (payload JSON-encoded).
|
|
263
|
+
const res = await xvm.call({
|
|
264
|
+
targetVm: "cosmwasm",
|
|
265
|
+
targetContract: "qor1contract…",
|
|
266
|
+
payload: { cosmwasm: { increment: {} } },
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// Atomic triple-VM batch in ONE tx.
|
|
270
|
+
const atomic = await xvm.callAtomic([
|
|
271
|
+
{ targetVm: "evm", targetContract: "0xC…", payload: { evm: { abi, functionName: "swap", args: [a, b] } } },
|
|
272
|
+
{ targetVm: "svm", targetContract: "Prog…", payload: { payload: rawBytes } },
|
|
273
|
+
{ targetVm: "cosmwasm", targetContract: "qor1…", payload: { cosmwasm: { stake: {} } } },
|
|
274
|
+
]);
|
|
275
|
+
|
|
276
|
+
// build-only (returns an EncodeObject) and read message status:
|
|
277
|
+
const msg = xvm.buildCall({ targetVm: "evm", targetContract: "0xC…", payload: { payload: rawBytes } });
|
|
278
|
+
const status = await xvm.getMessage("42");
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
`targetVm` is one of `"evm" | "cosmwasm" | "svm"` (see `VM_TYPES`). See the
|
|
282
|
+
[cross-VM](../../docs/docs/guides/cross-vm.md) guide.
|
|
283
|
+
|
|
284
|
+
### Quantum-safe DX (v0.5.0)
|
|
285
|
+
|
|
286
|
+
QoreChain enforces hybrid post-quantum signatures (ML-DSA-87 + secp256k1) by
|
|
287
|
+
default. These helpers make a dApp PQC-protected in one idempotent call: check
|
|
288
|
+
whether the signer's Dilithium key is registered, register it if not, and route
|
|
289
|
+
subsequent transactions through the hybrid signing path.
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
import {
|
|
293
|
+
isPqcRegistered,
|
|
294
|
+
getPqcStatus,
|
|
295
|
+
ensurePqcRegistered,
|
|
296
|
+
migrateToHybrid,
|
|
297
|
+
migratePqcKey,
|
|
298
|
+
} from "@qorechain/sdk";
|
|
299
|
+
|
|
300
|
+
// Read-only status (over the qor_ namespace or the pqcKeyStatus precompile).
|
|
301
|
+
const registered = await isPqcRegistered(client.qor, native.address);
|
|
302
|
+
const status = await getPqcStatus(client.qor, native.address);
|
|
303
|
+
|
|
304
|
+
// Idempotent: registers the signer's PQC key only if it isn't already.
|
|
305
|
+
await ensurePqcRegistered({ tx, signer: pqcSigner /* … */ });
|
|
306
|
+
|
|
307
|
+
// Migrate an existing classical account to hybrid signing, then sign hybrid.
|
|
308
|
+
const path = await migrateToHybrid({ tx, signer: pqcSigner /* … */ });
|
|
309
|
+
|
|
310
|
+
// Rotate an account's on-chain PQC key (MsgMigratePQCKey).
|
|
311
|
+
await migratePqcKey({ tx, /* new key material … */ });
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
See the [quantum-safe](../../docs/docs/guides/quantum-safe.md) guide.
|
|
315
|
+
|
|
316
|
+
### Cross-VM message reads
|
|
317
|
+
|
|
318
|
+
You can also read cross-VM message state without the client above:
|
|
149
319
|
|
|
150
320
|
```ts
|
|
151
321
|
const pending = await client.crossvm.pending();
|
package/dist/index.cjs
CHANGED
|
@@ -16,7 +16,7 @@ var english = require('@scure/bip39/wordlists/english');
|
|
|
16
16
|
var bip32 = require('@scure/bip32');
|
|
17
17
|
var slip10_js = require('micro-key-producer/slip10.js');
|
|
18
18
|
var secp256k1 = require('@noble/curves/secp256k1');
|
|
19
|
-
var
|
|
19
|
+
var pqc$1 = require('@qorechain/pqc');
|
|
20
20
|
var utils = require('@noble/hashes/utils');
|
|
21
21
|
var evm = require('@qorechain/evm');
|
|
22
22
|
var tendermintRpc = require('@cosmjs/tendermint-rpc');
|
|
@@ -443,7 +443,7 @@ var QorClient = class extends JsonRpcClient {
|
|
|
443
443
|
// src/tx/fees.ts
|
|
444
444
|
var STATIC_FALLBACK = {
|
|
445
445
|
/** Fallback gas price, in base denom per unit of gas. */
|
|
446
|
-
gasPrice: "0.
|
|
446
|
+
gasPrice: "0.15",
|
|
447
447
|
/** Base denomination fees are paid in. */
|
|
448
448
|
denom: "uqor",
|
|
449
449
|
/** Default gas limit when the caller does not supply one. */
|
|
@@ -9716,7 +9716,7 @@ function calculateFee(gas, gasPrice) {
|
|
|
9716
9716
|
// src/tx/builder.ts
|
|
9717
9717
|
var MSG_SEND_TYPE_URL = "/cosmos.bank.v1beta1.MsgSend";
|
|
9718
9718
|
var DEFAULT_GAS_MULTIPLIER = 1.4;
|
|
9719
|
-
var DEFAULT_GAS_PRICE = "0.
|
|
9719
|
+
var DEFAULT_GAS_PRICE = "0.15uqor";
|
|
9720
9720
|
function buildAminoTypes(extra) {
|
|
9721
9721
|
return new stargate.AminoTypes({
|
|
9722
9722
|
...stargate.createDefaultAminoConverters(),
|
|
@@ -9795,7 +9795,7 @@ var TxClient = class _TxClient {
|
|
|
9795
9795
|
*
|
|
9796
9796
|
* `fee` may be an explicit {@link StdFee} or the literal `"auto"`, which
|
|
9797
9797
|
* simulates the tx to estimate gas and computes the fee from a gas
|
|
9798
|
-
* multiplier (default 1.4) and gas price (default `0.
|
|
9798
|
+
* multiplier (default 1.4) and gas price (default `0.15uqor`); tune both via
|
|
9799
9799
|
* `opts.autoFee`.
|
|
9800
9800
|
*
|
|
9801
9801
|
* Broadcast mode maps onto cosmjs transports:
|
|
@@ -10451,14 +10451,14 @@ function generatePqcKeypair(seed) {
|
|
|
10451
10451
|
);
|
|
10452
10452
|
}
|
|
10453
10453
|
const xi = seed ?? utils.randomBytes(ML_DSA_87_SEED_LENGTH);
|
|
10454
|
-
const kp =
|
|
10454
|
+
const kp = pqc$1.mldsa87.keygen(xi);
|
|
10455
10455
|
return { publicKey: kp.publicKey, secretKey: kp.secretKey };
|
|
10456
10456
|
}
|
|
10457
|
-
function pqcSign(secretKey, message) {
|
|
10458
|
-
return
|
|
10457
|
+
function pqcSign(secretKey, message, opts) {
|
|
10458
|
+
return pqc$1.mldsa87.sign(secretKey, message, opts);
|
|
10459
10459
|
}
|
|
10460
10460
|
function pqcVerify(publicKey, message, signature) {
|
|
10461
|
-
return
|
|
10461
|
+
return pqc$1.mldsa87.verify(publicKey, message, signature);
|
|
10462
10462
|
}
|
|
10463
10463
|
function buildHybridSignatureExtension(args) {
|
|
10464
10464
|
const { algorithmId, signature, publicKey } = args;
|
|
@@ -19156,7 +19156,7 @@ function suggestChainInfo(network) {
|
|
|
19156
19156
|
};
|
|
19157
19157
|
const feeCurrency = {
|
|
19158
19158
|
...currency,
|
|
19159
|
-
gasPriceStep: { low: 0.
|
|
19159
|
+
gasPriceStep: { low: 0.1, average: 0.15, high: 0.25 }
|
|
19160
19160
|
};
|
|
19161
19161
|
return {
|
|
19162
19162
|
chainId,
|
|
@@ -19764,9 +19764,10 @@ async function isPqcRegistered(source, address) {
|
|
|
19764
19764
|
return status.registered;
|
|
19765
19765
|
}
|
|
19766
19766
|
function buildRegisterPqcKeyMsg(sender, opts) {
|
|
19767
|
-
return pqc.
|
|
19767
|
+
return pqc.registerPqcKeyV2({
|
|
19768
19768
|
sender,
|
|
19769
|
-
|
|
19769
|
+
publicKey: opts.pqcKeypair.publicKey,
|
|
19770
|
+
algorithmId: AlgorithmDilithium5,
|
|
19770
19771
|
ecdsaPubkey: opts.ecdsaPubkey ?? new Uint8Array(0),
|
|
19771
19772
|
keyType: opts.keyType ?? "hybrid"
|
|
19772
19773
|
});
|