@inversealtruism/cairn-sdk 0.7.0 → 0.8.1
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 +7 -8
- package/dist/{chunk-TDXGYP3G.js → chunk-23ATXZKM.js} +1 -1
- package/dist/{chunk-4FFLCCL4.js → chunk-F3KJPQXM.js} +1 -1
- package/dist/{chunk-XOGOSGC6.js → chunk-QWGR5J5D.js} +1 -1
- package/dist/{chunk-PBKDSDID.js → chunk-X7J6ECNV.js} +1 -1
- package/dist/connect.cjs +1 -1
- package/dist/connect.js +2 -2
- package/dist/content.cjs +1 -1
- package/dist/content.js +2 -2
- package/dist/controller.cjs +1 -1
- package/dist/controller.js +3 -3
- package/dist/index.cjs +34 -30
- package/dist/index.d.cts +19 -10
- package/dist/index.d.ts +19 -10
- package/dist/index.js +40 -38
- package/dist/react.cjs +1 -1
- package/dist/react.js +3 -3
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -39,8 +39,8 @@ cairn.index.streamAll({ onBlock: (e) => console.log("new block", e) });
|
|
|
39
39
|
|
|
40
40
|
The SDK follows the exact model MetaMask uses, there is **no allowlist you maintain**:
|
|
41
41
|
|
|
42
|
-
- **`connect()` / `getAddress()`** grant *address visibility*. The first time a site connects, the user approves once; after that the wallet answers silently (the site shows up under **Settings → Connected sites**, revocable anytime).
|
|
43
|
-
- **Every signing / fund-moving call:** `send`, `propose`, `attest`, `
|
|
42
|
+
- **`connect()` / `getAddress()`** grant *address visibility*. The first time a site connects, the user approves once; after that the wallet answers silently (the site shows up under **Settings → Connected sites**, revocable anytime). These are the only calls that can return the address without a prompt. `getPermissions()` (read this site's own grant) and `revokePermissions()` (drop it) are silent too; neither signs anything.
|
|
43
|
+
- **Every signing / fund-moving call:** `send`, `propose`, `attest`, `fillOffer`, `sealClaim`, `revealClaim` and `signInWithCsd`, **always** opens the wallet's clear-signing approval window, **every time**, no matter what. Being "connected" never pre-approves a signature. A connected site cannot move a satoshi without an explicit, fully-disclosed approval click. The legacy `signIn()` is deprecated and first-party-only: the wallet refuses it from any other site with `FIRST_PARTY_ONLY` before prompting; use `signInWithCsd()`.
|
|
44
44
|
|
|
45
45
|
```ts
|
|
46
46
|
import { connect, UserRejectedError, NotInstalledError } from "@inversealtruism/cairn-sdk";
|
|
@@ -58,7 +58,7 @@ try {
|
|
|
58
58
|
|
|
59
59
|
**`cairn.index`:** `tipHeight()`, `block()/blockTxids()`, `tx()/txStatus()/txMerkleProof()`, `address()/addressTxs()/addressUtxo()`, `domains()/domainProposals(domain)`, `proposal()/attestations()`, `reputation()`, **`verifyInclusion(txid)`** (trust-minimized), `streamAll()/streamBlocks()/streamDomain()` (SSE), `subscribe()` (WS).
|
|
60
60
|
|
|
61
|
-
**`cairn.names`:** `resolve(name)` (display-path name to address), `name(name)`/`nameHistory(name)`, `primary(addr)` (reverse lookup)/`namesOf(addr)`, `names()`, `tokens()/token(ticker)`, `offers()
|
|
61
|
+
**`cairn.names`:** `resolve(name)` (display-path name to address), `name(name)`/`nameHistory(name)`, `primary(addr)` (reverse lookup)/`namesOf(addr)`, `names()`, `tokens()/token(ticker)`, `offers()`/`bids()` (open rows by default; pass `{ status }` for another status, or `{ status: "all" }` for every row), `state()` (the canonical CairnX state). Reads go through the public `/trade/api/cairnx/*` proxy; for payment-grade name resolution verify through the wallet or a replaying resolver, not a bare read (see `src/names.ts` header).
|
|
62
62
|
|
|
63
63
|
**`cairn.content`:** `prepare(obj)`/`put(obj)` → `{ payloadHash, canonical, bytes }`; `get(hash)` / `getBytes(hash)` (fetch **and verify** `sha256(bytes) === hash`, throws `ContentVerificationError` on tamper); `hash(obj)`.
|
|
64
64
|
|
|
@@ -68,14 +68,13 @@ Subpath imports are available for tree-shaking: `@inversealtruism/cairn-sdk/{con
|
|
|
68
68
|
|
|
69
69
|
## Examples
|
|
70
70
|
|
|
71
|
-
- **`examples/read-only.mjs`:** runs
|
|
72
|
-
- **`examples/hello-csd/`:** a no-framework browser dApp (connect → read recent proposals → live feed). Build the bundle with `
|
|
71
|
+
- **`examples/read-only.mjs`:** runs against live mainnet with no wallet. It imports the built `dist/`, so run `pnpm build` first, then `pnpm test:live`. Demonstrates chain/indexer reads + verified merkle inclusion + verified content fetch.
|
|
72
|
+
- **`examples/hello-csd/`:** a no-framework browser dApp (connect → read recent proposals → live feed). Build the bundle with `pnpm build:example`, then serve the folder from **localhost** (the wallet injects there) with the Cairn Wallet installed.
|
|
73
73
|
|
|
74
74
|
## Trust model & honest limits
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
- **Balances are RPC-trusted.** Headers don't commit to the UTXO set; balance reads trust the node/proxy (same as every light client).
|
|
76
|
+
Content bytes are always verified client-side; merkle inclusion is verified when a PoW-verified header backs it (`trustLevel: "verified-inclusion"`); balances are RPC-trusted. The full trust model (each `trustLevel`, the checkpoint, reorgs near the tip) is in [`docs/SDK-GUIDE.md`](docs/SDK-GUIDE.md#what-the-sdk-verifies-vs-trusts-read-this).
|
|
77
|
+
|
|
79
78
|
- **Content comes from the cairn origin.** `cairn.content` reads `/content/<hash>` on the cairn base and verifies every byte against the hash.
|
|
80
79
|
- **The indexer runs behind the cairn proxy.** By default `cairn.index` uses the cairn server's hardened, read-only, rate-limited `/explorer/api` reverse proxy (no separate public indexer needed). **SSE works through that proxy; `subscribe()` (WebSocket) needs a direct indexer endpoint:** set `baseUrls.indexer` to a private/localhost indexer for WS.
|
|
81
80
|
- **The wallet injects on every site** (connect-anywhere shipped in 0.2.4x) behind a per-origin consent gate: a site sees nothing until the user approves the connection, and some request kinds stay first-party-only (the `FIRST_PARTY_ONLY` error code).
|
package/dist/connect.cjs
CHANGED
|
@@ -30,7 +30,7 @@ __export(connect_exports, {
|
|
|
30
30
|
module.exports = __toCommonJS(connect_exports);
|
|
31
31
|
|
|
32
32
|
// src/errors.ts
|
|
33
|
-
var SDK_VERSION = "0.
|
|
33
|
+
var SDK_VERSION = "0.8.1";
|
|
34
34
|
var DOCS_BASE = "https://cairn-substrate.com/docs/sdk";
|
|
35
35
|
var CairnError = class extends Error {
|
|
36
36
|
/** Stable machine code for programmatic branching. */
|
package/dist/connect.js
CHANGED
package/dist/content.cjs
CHANGED
|
@@ -26,7 +26,7 @@ module.exports = __toCommonJS(content_exports);
|
|
|
26
26
|
var import_csd_codec = require("@inversealtruism/csd-codec");
|
|
27
27
|
|
|
28
28
|
// src/errors.ts
|
|
29
|
-
var SDK_VERSION = "0.
|
|
29
|
+
var SDK_VERSION = "0.8.1";
|
|
30
30
|
var DOCS_BASE = "https://cairn-substrate.com/docs/sdk";
|
|
31
31
|
var CairnError = class extends Error {
|
|
32
32
|
/** Stable machine code for programmatic branching. */
|
package/dist/content.js
CHANGED
package/dist/controller.cjs
CHANGED
|
@@ -25,7 +25,7 @@ __export(controller_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(controller_exports);
|
|
26
26
|
|
|
27
27
|
// src/errors.ts
|
|
28
|
-
var SDK_VERSION = "0.
|
|
28
|
+
var SDK_VERSION = "0.8.1";
|
|
29
29
|
var DOCS_BASE = "https://cairn-substrate.com/docs/sdk";
|
|
30
30
|
var CairnError = class extends Error {
|
|
31
31
|
/** Stable machine code for programmatic branching. */
|
package/dist/controller.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -58,7 +58,7 @@ __export(index_exports, {
|
|
|
58
58
|
module.exports = __toCommonJS(index_exports);
|
|
59
59
|
|
|
60
60
|
// src/errors.ts
|
|
61
|
-
var SDK_VERSION = "0.
|
|
61
|
+
var SDK_VERSION = "0.8.1";
|
|
62
62
|
var DOCS_BASE = "https://cairn-substrate.com/docs/sdk";
|
|
63
63
|
var CairnError = class extends Error {
|
|
64
64
|
/** Stable machine code for programmatic branching. */
|
|
@@ -765,7 +765,8 @@ function normalizeHash(hash) {
|
|
|
765
765
|
// src/names.ts
|
|
766
766
|
var import_cairnx_core = require("@inversealtruism/cairnx-core");
|
|
767
767
|
var nameOk = (n) => typeof n === "string" && import_cairnx_core.NAME_RE.test(n) && !import_cairnx_core.RESERVED_NAMES.has(n);
|
|
768
|
-
var amountOk = (v) =>
|
|
768
|
+
var amountOk = (v) => (0, import_cairnx_core.parseAmount)(v, { allowZero: true }) !== null;
|
|
769
|
+
var decimalsOk = (d) => Number.isSafeInteger(d) && d >= 0 && d <= import_cairnx_core.MAX_TOKEN_DECIMALS;
|
|
769
770
|
var heightOk = (v) => Number.isSafeInteger(v) && v >= 0;
|
|
770
771
|
function nameHistoryProblem(h, name) {
|
|
771
772
|
if (!h || typeof h !== "object" || Array.isArray(h)) return "not an object";
|
|
@@ -782,14 +783,15 @@ function nameHistoryProblem(h, name) {
|
|
|
782
783
|
}
|
|
783
784
|
return null;
|
|
784
785
|
}
|
|
785
|
-
function tokenProblem(t) {
|
|
786
|
+
function tokenProblem(t, ticker) {
|
|
786
787
|
if (!t || typeof t !== "object") return "not an object";
|
|
787
788
|
const r = t;
|
|
788
789
|
if (typeof r.ticker !== "string" || !import_cairnx_core.TICKER_RE.test(r.ticker)) return "bad ticker";
|
|
789
|
-
if (
|
|
790
|
-
if (!
|
|
791
|
-
if (!amountOk(r.
|
|
792
|
-
if (
|
|
790
|
+
if (ticker !== void 0 && r.ticker !== ticker) return `ticker is ${JSON.stringify(r.ticker)}, expected ${JSON.stringify(ticker)}`;
|
|
791
|
+
if (!decimalsOk(r.decimals)) return `bad decimals (${String(r.decimals)}), not an integer in the consensus range`;
|
|
792
|
+
if (!amountOk(r.supply)) return "supply is not a base-unit integer string within MAX_AMOUNT";
|
|
793
|
+
if (!amountOk(r.minted)) return "minted is not a base-unit integer string within MAX_AMOUNT";
|
|
794
|
+
if (r.mintLimit !== void 0 && !amountOk(r.mintLimit)) return "mintLimit is not a base-unit integer string within MAX_AMOUNT";
|
|
793
795
|
return null;
|
|
794
796
|
}
|
|
795
797
|
var NamesClient = class {
|
|
@@ -800,11 +802,17 @@ var NamesClient = class {
|
|
|
800
802
|
malformed(path, what) {
|
|
801
803
|
return new HttpError(200, this.http.url(path), `malformed response: ${what}`);
|
|
802
804
|
}
|
|
803
|
-
async list(path) {
|
|
804
|
-
const body = await this.http.getJson(path);
|
|
805
|
+
async list(path, query) {
|
|
806
|
+
const body = await this.http.getJson(path, query);
|
|
805
807
|
if (!Array.isArray(body)) throw this.malformed(path, "expected an array");
|
|
806
808
|
return body;
|
|
807
809
|
}
|
|
810
|
+
/** Rows of a market list with one status, or every row for "all". */
|
|
811
|
+
async byStatus(path, status) {
|
|
812
|
+
if (status === "all") return this.list(path);
|
|
813
|
+
const rows = await this.list(path, { status });
|
|
814
|
+
return rows.filter((r) => r?.status === status);
|
|
815
|
+
}
|
|
808
816
|
/** Resolve a .csd name for DISPLAY (server-trusted; see the module trust note). null = unknown/invalid name. */
|
|
809
817
|
async resolve(name) {
|
|
810
818
|
if (!nameOk(name)) return null;
|
|
@@ -875,7 +883,8 @@ var NamesClient = class {
|
|
|
875
883
|
});
|
|
876
884
|
return rows;
|
|
877
885
|
}
|
|
878
|
-
/** One token by ticker. null = unknown/invalid ticker. Throws a typed HttpError on a malformed body
|
|
886
|
+
/** One token by ticker. null = unknown/invalid ticker. Throws a typed HttpError on a malformed body or a
|
|
887
|
+
* record for another ticker. */
|
|
879
888
|
async token(ticker) {
|
|
880
889
|
if (typeof ticker !== "string" || !import_cairnx_core.TICKER_RE.test(ticker)) return null;
|
|
881
890
|
const path = `/trade/api/cairnx/token/${ticker}`;
|
|
@@ -886,17 +895,19 @@ var NamesClient = class {
|
|
|
886
895
|
if (e?.status === 404) return null;
|
|
887
896
|
throw e;
|
|
888
897
|
}
|
|
889
|
-
const p = tokenProblem(t);
|
|
898
|
+
const p = tokenProblem(t, ticker);
|
|
890
899
|
if (p) throw this.malformed(path, p);
|
|
891
900
|
return t;
|
|
892
901
|
}
|
|
893
|
-
/**
|
|
894
|
-
|
|
895
|
-
|
|
902
|
+
/** Offers with one status, open ones by default (the market's display list). `{ status: "all" }` returns every
|
|
903
|
+
* offer the server holds, filled, cancelled and expired ones included. */
|
|
904
|
+
offers(opts = {}) {
|
|
905
|
+
return this.byStatus(`/trade/api/cairnx/offers`, opts.status ?? "open");
|
|
896
906
|
}
|
|
897
|
-
/**
|
|
898
|
-
|
|
899
|
-
|
|
907
|
+
/** Bids with one status, open ones by default. `{ status: "all" }` returns every bid the server holds, done,
|
|
908
|
+
* cancelled and expired ones included. */
|
|
909
|
+
bids(opts = {}) {
|
|
910
|
+
return this.byStatus(`/trade/api/cairnx/bids`, opts.status ?? "open");
|
|
900
911
|
}
|
|
901
912
|
/** The full canonical CairnX state (large; prefer the scoped reads above). */
|
|
902
913
|
state() {
|
|
@@ -1161,6 +1172,7 @@ async function connect(opts = {}) {
|
|
|
1161
1172
|
// src/fillverify.ts
|
|
1162
1173
|
var import_csd_client3 = require("@inversealtruism/csd-client");
|
|
1163
1174
|
var import_csd_codec4 = require("@inversealtruism/csd-codec");
|
|
1175
|
+
var import_csd_crypto3 = require("@inversealtruism/csd-crypto");
|
|
1164
1176
|
var import_cairnx_core2 = require("@inversealtruism/cairnx-core");
|
|
1165
1177
|
var ADDR = /^0x[0-9a-f]{40}$/;
|
|
1166
1178
|
var BELOW_BASE = /^tx below the synced base \((\d+)\)/;
|
|
@@ -1201,9 +1213,7 @@ async function provenAuthor(client, provenTx) {
|
|
|
1201
1213
|
return null;
|
|
1202
1214
|
}
|
|
1203
1215
|
if (String((0, import_csd_codec4.txid)(src)).toLowerCase() !== String(in0.prevTxid).toLowerCase()) return null;
|
|
1204
|
-
|
|
1205
|
-
const spk = out?.scriptPubkey ? String(out.scriptPubkey).toLowerCase() : null;
|
|
1206
|
-
return spk && ADDR.test(spk) ? spk : null;
|
|
1216
|
+
return (0, import_csd_crypto3.authorOf)(provenTx, src.outputs?.[Number(in0.vout)]?.scriptPubkey);
|
|
1207
1217
|
}
|
|
1208
1218
|
async function preverifyOffer(opts) {
|
|
1209
1219
|
const id = String(opts.offerId).toLowerCase();
|
|
@@ -1231,8 +1241,6 @@ async function preverifyOffer(opts) {
|
|
|
1231
1241
|
if (String(provenId).toLowerCase() !== id) return { ok: false, trust: "unverified", reason: "the merkle-proven tx doesn't match the offer id" };
|
|
1232
1242
|
const app = incl.tx.app;
|
|
1233
1243
|
if (!app || app.type !== "Propose") return { ok: false, trust: "unverified", reason: "the offer tx is not a Propose" };
|
|
1234
|
-
if (String(app.domain) !== import_cairnx_core2.DOMAIN)
|
|
1235
|
-
return { ok: false, trust: "unverified", reason: `the offer tx is not a ${import_cairnx_core2.DOMAIN} Propose (wrong settlement domain)` };
|
|
1236
1244
|
let rec;
|
|
1237
1245
|
try {
|
|
1238
1246
|
rec = (0, import_cairnx_core2.parseRecord)(app.uri, incl.appPayloadHash);
|
|
@@ -1245,14 +1253,12 @@ async function preverifyOffer(opts) {
|
|
|
1245
1253
|
const seller = await provenAuthor(opts.client, provenTx);
|
|
1246
1254
|
if (!seller) return { ok: false, trust: "verified", transient: true, blockHeight, reason: "couldn't prove the offer's on-chain author yet; the chain view may be catching up, try again" };
|
|
1247
1255
|
const offerRec = rec;
|
|
1256
|
+
const ee = app.expires_epoch;
|
|
1257
|
+
const refusal = (0, import_cairnx_core2.provenOfferRefusal)(offerRec, { domain: String(app.domain), height: blockHeight, expiresEpoch: typeof ee === "bigint" ? ee : Number(ee), seller });
|
|
1258
|
+
if (refusal) return { ok: false, trust: "verified", blockHeight, reason: `CairnX rejects this offer (${refusal}) - a fill would move CSD for nothing` };
|
|
1248
1259
|
const w = rec.want ?? {};
|
|
1249
1260
|
const payto = w.payto && ADDR.test(String(w.payto).toLowerCase()) ? String(w.payto).toLowerCase() : seller;
|
|
1250
1261
|
const terms = (0, import_cairnx_core2.provenOfferTerms)(offerRec, blockHeight);
|
|
1251
|
-
if (payto === import_cairnx_core2.TREASURY_ADDR)
|
|
1252
|
-
return { ok: false, trust: "verified", blockHeight, reason: "the offer's payment recipient is the protocol treasury - the chain rejects it, and a fill would move CSD for nothing" };
|
|
1253
|
-
const provenExpiresEpoch = Number(app.expires_epoch);
|
|
1254
|
-
if (!Number.isSafeInteger(provenExpiresEpoch) || (0, import_cairnx_core2.epochOf)(blockHeight) > provenExpiresEpoch)
|
|
1255
|
-
return { ok: false, trust: "verified", blockHeight, reason: "the offer was already expired when it was mined - the chain rejects it, and a fill would move CSD for nothing" };
|
|
1256
1262
|
let outputPlan;
|
|
1257
1263
|
let sumsMismatch;
|
|
1258
1264
|
let planReason;
|
|
@@ -1310,9 +1316,7 @@ async function preverifyOffer(opts) {
|
|
|
1310
1316
|
if (String(so.seller).toLowerCase() !== seller)
|
|
1311
1317
|
return { ok: false, trust: "verified", reason: "the served seller doesn't match the offer's on-chain author (a lying resolver may be redirecting your payment)", ...base };
|
|
1312
1318
|
if ((0, import_cairnx_core2.bindOfferTerms)(opts.servedOffer, terms, { give: true, wantType: true }))
|
|
1313
|
-
return { ok: false, trust: "verified", reason: "the served terms don't match the offer's on-chain record (fee, rebate, partial sizing, the give, or the want type - a lying resolver could mis-size or re-route the fill, redirecting or burning your payment)", ...base };
|
|
1314
|
-
if ((0, import_cairnx_core2.isTokenWant)(offerRec.want) && (String(so?.want?.ticker) !== String(offerRec.want.ticker) || String(so?.want?.amount) !== String(offerRec.want.amount)))
|
|
1315
|
-
return { ok: false, trust: "verified", reason: "the served want ticker/amount don't match the offer's on-chain record (a lying resolver could bait-and-switch the token price)", ...base };
|
|
1319
|
+
return { ok: false, trust: "verified", reason: "the served terms don't match the offer's on-chain record (fee, rebate, partial sizing, the give, or the want's type or token price - a lying resolver could mis-size, re-price or re-route the fill, redirecting or burning your payment)", ...base };
|
|
1316
1320
|
}
|
|
1317
1321
|
if (sumsMismatch) return { ok: false, trust: "verified", reason: sumsMismatch, ...base };
|
|
1318
1322
|
return { ok: true, trust: "verified", ...base };
|
package/dist/index.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ import { IndexerClient } from './indexer.cjs';
|
|
|
5
5
|
export { InclusionResult, IndexEvent, MerkleProof, StreamHandle, StreamHandlers, TrustLevel } from './indexer.cjs';
|
|
6
6
|
import { ContentClient } from './content.cjs';
|
|
7
7
|
export { ContentClientOptions, PreparedContent } from './content.cjs';
|
|
8
|
-
import { NameState, MintedProvenOfferTerms } from '@inversealtruism/cairnx-core';
|
|
8
|
+
import { NameState, OfferStatus, BidStatus, MintedProvenOfferTerms } from '@inversealtruism/cairnx-core';
|
|
9
9
|
export { FillEndorsement, FillOutputPlan, FillPreview, FillSafety, MintedProvenOfferTerms, ProvenOfferTerms, bindOfferTerms, feeBpsAt, fillEndorsement, fillIsSafe, fillOutputPlan, previewFill, requiredFillOutputs } from '@inversealtruism/cairnx-core';
|
|
10
10
|
import { WalletConnection, DetectOptions } from './connect.cjs';
|
|
11
11
|
export { AttestParams, CairnProvider, ConnectResult, FillParams, ProposeParams, ProviderDetail, ProviderInfo, SealClaimParams, SendParams, SignInResult, SiwcParams, SiwcResult, TxResult, WalletCapabilities, WalletPermission, connect, detectProvider, discoverProviders, getWallet, isInstalled } from './connect.cjs';
|
|
@@ -16,7 +16,7 @@ import '@inversealtruism/csd-tx';
|
|
|
16
16
|
import '@inversealtruism/csd-codec';
|
|
17
17
|
import '@inversealtruism/csd-crypto';
|
|
18
18
|
|
|
19
|
-
/** `/cairnx/resolve/:name
|
|
19
|
+
/** `/cairnx/resolve/:name`: the display-path name→address resolution. */
|
|
20
20
|
interface NameResolution {
|
|
21
21
|
ok: boolean;
|
|
22
22
|
name: string;
|
|
@@ -28,7 +28,7 @@ interface NameResolution {
|
|
|
28
28
|
owner?: string;
|
|
29
29
|
tipHeight?: number;
|
|
30
30
|
}
|
|
31
|
-
/** `/cairnx/name/:name
|
|
31
|
+
/** `/cairnx/name/:name`: full name detail (lease, lock, resting offer, recapture window). */
|
|
32
32
|
interface NameDetail {
|
|
33
33
|
name: string;
|
|
34
34
|
owner: string;
|
|
@@ -101,6 +101,8 @@ declare class NamesClient {
|
|
|
101
101
|
constructor(http: Http);
|
|
102
102
|
private malformed;
|
|
103
103
|
private list;
|
|
104
|
+
/** Rows of a market list with one status, or every row for "all". */
|
|
105
|
+
private byStatus;
|
|
104
106
|
/** Resolve a .csd name for DISPLAY (server-trusted; see the module trust note). null = unknown/invalid name. */
|
|
105
107
|
resolve(name: string): Promise<NameResolution | null>;
|
|
106
108
|
/** Full detail for one name (lease, lock, resting offer, recapture). null = not registered/invalid. */
|
|
@@ -116,12 +118,19 @@ declare class NamesClient {
|
|
|
116
118
|
names(): Promise<unknown[]>;
|
|
117
119
|
/** All deployed tokens. Throws a typed HttpError if any row has a malformed ticker, decimals or amount. */
|
|
118
120
|
tokens(): Promise<TokenInfo[]>;
|
|
119
|
-
/** One token by ticker. null = unknown/invalid ticker. Throws a typed HttpError on a malformed body
|
|
121
|
+
/** One token by ticker. null = unknown/invalid ticker. Throws a typed HttpError on a malformed body or a
|
|
122
|
+
* record for another ticker. */
|
|
120
123
|
token(ticker: string): Promise<TokenInfo | null>;
|
|
121
|
-
/**
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
124
|
+
/** Offers with one status, open ones by default (the market's display list). `{ status: "all" }` returns every
|
|
125
|
+
* offer the server holds, filled, cancelled and expired ones included. */
|
|
126
|
+
offers(opts?: {
|
|
127
|
+
status?: OfferStatus | "all";
|
|
128
|
+
}): Promise<unknown[]>;
|
|
129
|
+
/** Bids with one status, open ones by default. `{ status: "all" }` returns every bid the server holds, done,
|
|
130
|
+
* cancelled and expired ones included. */
|
|
131
|
+
bids(opts?: {
|
|
132
|
+
status?: BidStatus | "all";
|
|
133
|
+
}): Promise<unknown[]>;
|
|
125
134
|
/** The full canonical CairnX state (large; prefer the scoped reads above). */
|
|
126
135
|
state(): Promise<unknown>;
|
|
127
136
|
}
|
|
@@ -189,7 +198,7 @@ declare function preverifyOffer(opts: {
|
|
|
189
198
|
|
|
190
199
|
/** Stable machine-readable error codes (branch on these, not the message text). */
|
|
191
200
|
type CairnErrorCode = "NOT_INSTALLED" | "USER_REJECTED" | "WALLET_LOCKED" | "UNSUPPORTED_METHOD" | "HTTP_ERROR" | "CONTENT_VERIFICATION" | "CONTENT_NOT_JSON" | "ACCOUNT_CHANGED" | "FIRST_PARTY_ONLY" | "RATE_LIMITED" | "APPROVAL_CLOSED" | "FORBIDDEN" | "INTERNAL" | "GHOST_INPUTS_SKIPPED" | "VERIFY_UNAVAILABLE" | "VERIFY_TAMPER" | "INSUFFICIENT" | "TOO_MANY_INPUTS" | "FEE_TOO_LOW" | "FEE_CAP" | "BAD_FEE" | "ZERO_ADDR_REFUSED" | "BAD_OUTPUTS" | "NO_OUTPUTS" | "BAD_REQUEST" | "OFFER_UNKNOWN" | "FILL_UNSAFE" | "FILL_WRONG_TARGET" | "SOURCE_DIVERGENCE" | "SUBMIT_REJECTED" | "SUBMIT_MAYBE_INFLIGHT" | "SUBMIT_DUPLICATE" | "NOTHING_TO_CONSOLIDATE" | "OFFER_SOURCE_CONFLICT" | "FILL_LEGACY_SUNSET" | "VERIFY_HORIZON" | "VERIFY_UNREPRESENTABLE" | "WALLET_UNAVAILABLE" | "REVIEW_REQUIRED" | "UNKNOWN";
|
|
192
|
-
declare const SDK_VERSION = "0.
|
|
201
|
+
declare const SDK_VERSION = "0.8.1";
|
|
193
202
|
interface CairnErrorOptions {
|
|
194
203
|
code?: CairnErrorCode;
|
|
195
204
|
docsPath?: string;
|
|
@@ -209,7 +218,7 @@ declare class CairnError extends Error {
|
|
|
209
218
|
/** Relative docs path (under the SDK docs base), if any. */
|
|
210
219
|
readonly docsPath?: string;
|
|
211
220
|
/** The cairn-sdk version that produced this error. */
|
|
212
|
-
readonly version = "0.
|
|
221
|
+
readonly version = "0.8.1";
|
|
213
222
|
/**
|
|
214
223
|
* Whether a dApp may safely AUTO-retry this failure. `false` for fund-safety refusals and user-intent
|
|
215
224
|
* declines (the default); `true` only for provably transient infra faults where nothing was signed.
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { IndexerClient } from './indexer.js';
|
|
|
5
5
|
export { InclusionResult, IndexEvent, MerkleProof, StreamHandle, StreamHandlers, TrustLevel } from './indexer.js';
|
|
6
6
|
import { ContentClient } from './content.js';
|
|
7
7
|
export { ContentClientOptions, PreparedContent } from './content.js';
|
|
8
|
-
import { NameState, MintedProvenOfferTerms } from '@inversealtruism/cairnx-core';
|
|
8
|
+
import { NameState, OfferStatus, BidStatus, MintedProvenOfferTerms } from '@inversealtruism/cairnx-core';
|
|
9
9
|
export { FillEndorsement, FillOutputPlan, FillPreview, FillSafety, MintedProvenOfferTerms, ProvenOfferTerms, bindOfferTerms, feeBpsAt, fillEndorsement, fillIsSafe, fillOutputPlan, previewFill, requiredFillOutputs } from '@inversealtruism/cairnx-core';
|
|
10
10
|
import { WalletConnection, DetectOptions } from './connect.js';
|
|
11
11
|
export { AttestParams, CairnProvider, ConnectResult, FillParams, ProposeParams, ProviderDetail, ProviderInfo, SealClaimParams, SendParams, SignInResult, SiwcParams, SiwcResult, TxResult, WalletCapabilities, WalletPermission, connect, detectProvider, discoverProviders, getWallet, isInstalled } from './connect.js';
|
|
@@ -16,7 +16,7 @@ import '@inversealtruism/csd-tx';
|
|
|
16
16
|
import '@inversealtruism/csd-codec';
|
|
17
17
|
import '@inversealtruism/csd-crypto';
|
|
18
18
|
|
|
19
|
-
/** `/cairnx/resolve/:name
|
|
19
|
+
/** `/cairnx/resolve/:name`: the display-path name→address resolution. */
|
|
20
20
|
interface NameResolution {
|
|
21
21
|
ok: boolean;
|
|
22
22
|
name: string;
|
|
@@ -28,7 +28,7 @@ interface NameResolution {
|
|
|
28
28
|
owner?: string;
|
|
29
29
|
tipHeight?: number;
|
|
30
30
|
}
|
|
31
|
-
/** `/cairnx/name/:name
|
|
31
|
+
/** `/cairnx/name/:name`: full name detail (lease, lock, resting offer, recapture window). */
|
|
32
32
|
interface NameDetail {
|
|
33
33
|
name: string;
|
|
34
34
|
owner: string;
|
|
@@ -101,6 +101,8 @@ declare class NamesClient {
|
|
|
101
101
|
constructor(http: Http);
|
|
102
102
|
private malformed;
|
|
103
103
|
private list;
|
|
104
|
+
/** Rows of a market list with one status, or every row for "all". */
|
|
105
|
+
private byStatus;
|
|
104
106
|
/** Resolve a .csd name for DISPLAY (server-trusted; see the module trust note). null = unknown/invalid name. */
|
|
105
107
|
resolve(name: string): Promise<NameResolution | null>;
|
|
106
108
|
/** Full detail for one name (lease, lock, resting offer, recapture). null = not registered/invalid. */
|
|
@@ -116,12 +118,19 @@ declare class NamesClient {
|
|
|
116
118
|
names(): Promise<unknown[]>;
|
|
117
119
|
/** All deployed tokens. Throws a typed HttpError if any row has a malformed ticker, decimals or amount. */
|
|
118
120
|
tokens(): Promise<TokenInfo[]>;
|
|
119
|
-
/** One token by ticker. null = unknown/invalid ticker. Throws a typed HttpError on a malformed body
|
|
121
|
+
/** One token by ticker. null = unknown/invalid ticker. Throws a typed HttpError on a malformed body or a
|
|
122
|
+
* record for another ticker. */
|
|
120
123
|
token(ticker: string): Promise<TokenInfo | null>;
|
|
121
|
-
/**
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
124
|
+
/** Offers with one status, open ones by default (the market's display list). `{ status: "all" }` returns every
|
|
125
|
+
* offer the server holds, filled, cancelled and expired ones included. */
|
|
126
|
+
offers(opts?: {
|
|
127
|
+
status?: OfferStatus | "all";
|
|
128
|
+
}): Promise<unknown[]>;
|
|
129
|
+
/** Bids with one status, open ones by default. `{ status: "all" }` returns every bid the server holds, done,
|
|
130
|
+
* cancelled and expired ones included. */
|
|
131
|
+
bids(opts?: {
|
|
132
|
+
status?: BidStatus | "all";
|
|
133
|
+
}): Promise<unknown[]>;
|
|
125
134
|
/** The full canonical CairnX state (large; prefer the scoped reads above). */
|
|
126
135
|
state(): Promise<unknown>;
|
|
127
136
|
}
|
|
@@ -189,7 +198,7 @@ declare function preverifyOffer(opts: {
|
|
|
189
198
|
|
|
190
199
|
/** Stable machine-readable error codes (branch on these, not the message text). */
|
|
191
200
|
type CairnErrorCode = "NOT_INSTALLED" | "USER_REJECTED" | "WALLET_LOCKED" | "UNSUPPORTED_METHOD" | "HTTP_ERROR" | "CONTENT_VERIFICATION" | "CONTENT_NOT_JSON" | "ACCOUNT_CHANGED" | "FIRST_PARTY_ONLY" | "RATE_LIMITED" | "APPROVAL_CLOSED" | "FORBIDDEN" | "INTERNAL" | "GHOST_INPUTS_SKIPPED" | "VERIFY_UNAVAILABLE" | "VERIFY_TAMPER" | "INSUFFICIENT" | "TOO_MANY_INPUTS" | "FEE_TOO_LOW" | "FEE_CAP" | "BAD_FEE" | "ZERO_ADDR_REFUSED" | "BAD_OUTPUTS" | "NO_OUTPUTS" | "BAD_REQUEST" | "OFFER_UNKNOWN" | "FILL_UNSAFE" | "FILL_WRONG_TARGET" | "SOURCE_DIVERGENCE" | "SUBMIT_REJECTED" | "SUBMIT_MAYBE_INFLIGHT" | "SUBMIT_DUPLICATE" | "NOTHING_TO_CONSOLIDATE" | "OFFER_SOURCE_CONFLICT" | "FILL_LEGACY_SUNSET" | "VERIFY_HORIZON" | "VERIFY_UNREPRESENTABLE" | "WALLET_UNAVAILABLE" | "REVIEW_REQUIRED" | "UNKNOWN";
|
|
192
|
-
declare const SDK_VERSION = "0.
|
|
201
|
+
declare const SDK_VERSION = "0.8.1";
|
|
193
202
|
interface CairnErrorOptions {
|
|
194
203
|
code?: CairnErrorCode;
|
|
195
204
|
docsPath?: string;
|
|
@@ -209,7 +218,7 @@ declare class CairnError extends Error {
|
|
|
209
218
|
/** Relative docs path (under the SDK docs base), if any. */
|
|
210
219
|
readonly docsPath?: string;
|
|
211
220
|
/** The cairn-sdk version that produced this error. */
|
|
212
|
-
readonly version = "0.
|
|
221
|
+
readonly version = "0.8.1";
|
|
213
222
|
/**
|
|
214
223
|
* Whether a dApp may safely AUTO-retry this failure. `false` for fund-safety refusals and user-intent
|
|
215
224
|
* declines (the default); `true` only for provably transient infra faults where nothing was signed.
|
package/dist/index.js
CHANGED
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
} from "./chunk-C452UODV.js";
|
|
5
5
|
import {
|
|
6
6
|
ContentClient
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-23ATXZKM.js";
|
|
8
8
|
import {
|
|
9
9
|
IndexerClient
|
|
10
10
|
} from "./chunk-CI7YODPP.js";
|
|
11
11
|
import {
|
|
12
12
|
CairnController
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-QWGR5J5D.js";
|
|
14
14
|
import {
|
|
15
15
|
WalletConnection,
|
|
16
16
|
connect,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
discoverProviders,
|
|
19
19
|
getWallet,
|
|
20
20
|
isInstalled
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-F3KJPQXM.js";
|
|
22
22
|
import {
|
|
23
23
|
CairnError,
|
|
24
24
|
ContentVerificationError,
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
errorCode,
|
|
33
33
|
mapProviderError,
|
|
34
34
|
mapSubmitResultError
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-X7J6ECNV.js";
|
|
36
36
|
|
|
37
37
|
// src/http.ts
|
|
38
38
|
var DEFAULT_MAX_BYTES = 16 * 1024 * 1024;
|
|
@@ -203,9 +203,10 @@ function errText(body) {
|
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
// src/names.ts
|
|
206
|
-
import { NAME_RE, RESERVED_NAMES, TICKER_RE,
|
|
206
|
+
import { NAME_RE, RESERVED_NAMES, TICKER_RE, HASH_RE, MAX_TOKEN_DECIMALS, parseAmount } from "@inversealtruism/cairnx-core";
|
|
207
207
|
var nameOk = (n) => typeof n === "string" && NAME_RE.test(n) && !RESERVED_NAMES.has(n);
|
|
208
|
-
var amountOk = (v) =>
|
|
208
|
+
var amountOk = (v) => parseAmount(v, { allowZero: true }) !== null;
|
|
209
|
+
var decimalsOk = (d) => Number.isSafeInteger(d) && d >= 0 && d <= MAX_TOKEN_DECIMALS;
|
|
209
210
|
var heightOk = (v) => Number.isSafeInteger(v) && v >= 0;
|
|
210
211
|
function nameHistoryProblem(h, name) {
|
|
211
212
|
if (!h || typeof h !== "object" || Array.isArray(h)) return "not an object";
|
|
@@ -222,14 +223,15 @@ function nameHistoryProblem(h, name) {
|
|
|
222
223
|
}
|
|
223
224
|
return null;
|
|
224
225
|
}
|
|
225
|
-
function tokenProblem(t) {
|
|
226
|
+
function tokenProblem(t, ticker) {
|
|
226
227
|
if (!t || typeof t !== "object") return "not an object";
|
|
227
228
|
const r = t;
|
|
228
229
|
if (typeof r.ticker !== "string" || !TICKER_RE.test(r.ticker)) return "bad ticker";
|
|
229
|
-
if (
|
|
230
|
-
if (!
|
|
231
|
-
if (!amountOk(r.
|
|
232
|
-
if (
|
|
230
|
+
if (ticker !== void 0 && r.ticker !== ticker) return `ticker is ${JSON.stringify(r.ticker)}, expected ${JSON.stringify(ticker)}`;
|
|
231
|
+
if (!decimalsOk(r.decimals)) return `bad decimals (${String(r.decimals)}), not an integer in the consensus range`;
|
|
232
|
+
if (!amountOk(r.supply)) return "supply is not a base-unit integer string within MAX_AMOUNT";
|
|
233
|
+
if (!amountOk(r.minted)) return "minted is not a base-unit integer string within MAX_AMOUNT";
|
|
234
|
+
if (r.mintLimit !== void 0 && !amountOk(r.mintLimit)) return "mintLimit is not a base-unit integer string within MAX_AMOUNT";
|
|
233
235
|
return null;
|
|
234
236
|
}
|
|
235
237
|
var NamesClient = class {
|
|
@@ -240,11 +242,17 @@ var NamesClient = class {
|
|
|
240
242
|
malformed(path, what) {
|
|
241
243
|
return new HttpError(200, this.http.url(path), `malformed response: ${what}`);
|
|
242
244
|
}
|
|
243
|
-
async list(path) {
|
|
244
|
-
const body = await this.http.getJson(path);
|
|
245
|
+
async list(path, query) {
|
|
246
|
+
const body = await this.http.getJson(path, query);
|
|
245
247
|
if (!Array.isArray(body)) throw this.malformed(path, "expected an array");
|
|
246
248
|
return body;
|
|
247
249
|
}
|
|
250
|
+
/** Rows of a market list with one status, or every row for "all". */
|
|
251
|
+
async byStatus(path, status) {
|
|
252
|
+
if (status === "all") return this.list(path);
|
|
253
|
+
const rows = await this.list(path, { status });
|
|
254
|
+
return rows.filter((r) => r?.status === status);
|
|
255
|
+
}
|
|
248
256
|
/** Resolve a .csd name for DISPLAY (server-trusted; see the module trust note). null = unknown/invalid name. */
|
|
249
257
|
async resolve(name) {
|
|
250
258
|
if (!nameOk(name)) return null;
|
|
@@ -315,7 +323,8 @@ var NamesClient = class {
|
|
|
315
323
|
});
|
|
316
324
|
return rows;
|
|
317
325
|
}
|
|
318
|
-
/** One token by ticker. null = unknown/invalid ticker. Throws a typed HttpError on a malformed body
|
|
326
|
+
/** One token by ticker. null = unknown/invalid ticker. Throws a typed HttpError on a malformed body or a
|
|
327
|
+
* record for another ticker. */
|
|
319
328
|
async token(ticker) {
|
|
320
329
|
if (typeof ticker !== "string" || !TICKER_RE.test(ticker)) return null;
|
|
321
330
|
const path = `/trade/api/cairnx/token/${ticker}`;
|
|
@@ -326,17 +335,19 @@ var NamesClient = class {
|
|
|
326
335
|
if (e?.status === 404) return null;
|
|
327
336
|
throw e;
|
|
328
337
|
}
|
|
329
|
-
const p = tokenProblem(t);
|
|
338
|
+
const p = tokenProblem(t, ticker);
|
|
330
339
|
if (p) throw this.malformed(path, p);
|
|
331
340
|
return t;
|
|
332
341
|
}
|
|
333
|
-
/**
|
|
334
|
-
|
|
335
|
-
|
|
342
|
+
/** Offers with one status, open ones by default (the market's display list). `{ status: "all" }` returns every
|
|
343
|
+
* offer the server holds, filled, cancelled and expired ones included. */
|
|
344
|
+
offers(opts = {}) {
|
|
345
|
+
return this.byStatus(`/trade/api/cairnx/offers`, opts.status ?? "open");
|
|
336
346
|
}
|
|
337
|
-
/**
|
|
338
|
-
|
|
339
|
-
|
|
347
|
+
/** Bids with one status, open ones by default. `{ status: "all" }` returns every bid the server holds, done,
|
|
348
|
+
* cancelled and expired ones included. */
|
|
349
|
+
bids(opts = {}) {
|
|
350
|
+
return this.byStatus(`/trade/api/cairnx/bids`, opts.status ?? "open");
|
|
340
351
|
}
|
|
341
352
|
/** The full canonical CairnX state (large; prefer the scoped reads above). */
|
|
342
353
|
state() {
|
|
@@ -347,20 +358,19 @@ var NamesClient = class {
|
|
|
347
358
|
// src/fillverify.ts
|
|
348
359
|
import { rpcTxToTx } from "@inversealtruism/csd-client";
|
|
349
360
|
import { txid, payloadHash } from "@inversealtruism/csd-codec";
|
|
361
|
+
import { authorOf } from "@inversealtruism/csd-crypto";
|
|
350
362
|
import {
|
|
351
|
-
DOMAIN,
|
|
352
363
|
parseRecord,
|
|
353
364
|
feeBpsAt,
|
|
354
365
|
bindOfferTerms,
|
|
355
366
|
provenOfferTerms,
|
|
367
|
+
provenOfferRefusal,
|
|
356
368
|
fillOutputPlan,
|
|
357
369
|
isTokenWant,
|
|
358
370
|
fillEndorsement,
|
|
359
371
|
fillIsSafe,
|
|
360
372
|
requiredFillOutputs,
|
|
361
|
-
previewFill
|
|
362
|
-
TREASURY_ADDR,
|
|
363
|
-
epochOf
|
|
373
|
+
previewFill
|
|
364
374
|
} from "@inversealtruism/cairnx-core";
|
|
365
375
|
var ADDR = /^0x[0-9a-f]{40}$/;
|
|
366
376
|
var BELOW_BASE = /^tx below the synced base \((\d+)\)/;
|
|
@@ -401,9 +411,7 @@ async function provenAuthor(client, provenTx) {
|
|
|
401
411
|
return null;
|
|
402
412
|
}
|
|
403
413
|
if (String(txid(src)).toLowerCase() !== String(in0.prevTxid).toLowerCase()) return null;
|
|
404
|
-
|
|
405
|
-
const spk = out?.scriptPubkey ? String(out.scriptPubkey).toLowerCase() : null;
|
|
406
|
-
return spk && ADDR.test(spk) ? spk : null;
|
|
414
|
+
return authorOf(provenTx, src.outputs?.[Number(in0.vout)]?.scriptPubkey);
|
|
407
415
|
}
|
|
408
416
|
async function preverifyOffer(opts) {
|
|
409
417
|
const id = String(opts.offerId).toLowerCase();
|
|
@@ -431,8 +439,6 @@ async function preverifyOffer(opts) {
|
|
|
431
439
|
if (String(provenId).toLowerCase() !== id) return { ok: false, trust: "unverified", reason: "the merkle-proven tx doesn't match the offer id" };
|
|
432
440
|
const app = incl.tx.app;
|
|
433
441
|
if (!app || app.type !== "Propose") return { ok: false, trust: "unverified", reason: "the offer tx is not a Propose" };
|
|
434
|
-
if (String(app.domain) !== DOMAIN)
|
|
435
|
-
return { ok: false, trust: "unverified", reason: `the offer tx is not a ${DOMAIN} Propose (wrong settlement domain)` };
|
|
436
442
|
let rec;
|
|
437
443
|
try {
|
|
438
444
|
rec = parseRecord(app.uri, incl.appPayloadHash);
|
|
@@ -445,14 +451,12 @@ async function preverifyOffer(opts) {
|
|
|
445
451
|
const seller = await provenAuthor(opts.client, provenTx);
|
|
446
452
|
if (!seller) return { ok: false, trust: "verified", transient: true, blockHeight, reason: "couldn't prove the offer's on-chain author yet; the chain view may be catching up, try again" };
|
|
447
453
|
const offerRec = rec;
|
|
454
|
+
const ee = app.expires_epoch;
|
|
455
|
+
const refusal = provenOfferRefusal(offerRec, { domain: String(app.domain), height: blockHeight, expiresEpoch: typeof ee === "bigint" ? ee : Number(ee), seller });
|
|
456
|
+
if (refusal) return { ok: false, trust: "verified", blockHeight, reason: `CairnX rejects this offer (${refusal}) - a fill would move CSD for nothing` };
|
|
448
457
|
const w = rec.want ?? {};
|
|
449
458
|
const payto = w.payto && ADDR.test(String(w.payto).toLowerCase()) ? String(w.payto).toLowerCase() : seller;
|
|
450
459
|
const terms = provenOfferTerms(offerRec, blockHeight);
|
|
451
|
-
if (payto === TREASURY_ADDR)
|
|
452
|
-
return { ok: false, trust: "verified", blockHeight, reason: "the offer's payment recipient is the protocol treasury - the chain rejects it, and a fill would move CSD for nothing" };
|
|
453
|
-
const provenExpiresEpoch = Number(app.expires_epoch);
|
|
454
|
-
if (!Number.isSafeInteger(provenExpiresEpoch) || epochOf(blockHeight) > provenExpiresEpoch)
|
|
455
|
-
return { ok: false, trust: "verified", blockHeight, reason: "the offer was already expired when it was mined - the chain rejects it, and a fill would move CSD for nothing" };
|
|
456
460
|
let outputPlan;
|
|
457
461
|
let sumsMismatch;
|
|
458
462
|
let planReason;
|
|
@@ -510,9 +514,7 @@ async function preverifyOffer(opts) {
|
|
|
510
514
|
if (String(so.seller).toLowerCase() !== seller)
|
|
511
515
|
return { ok: false, trust: "verified", reason: "the served seller doesn't match the offer's on-chain author (a lying resolver may be redirecting your payment)", ...base };
|
|
512
516
|
if (bindOfferTerms(opts.servedOffer, terms, { give: true, wantType: true }))
|
|
513
|
-
return { ok: false, trust: "verified", reason: "the served terms don't match the offer's on-chain record (fee, rebate, partial sizing, the give, or the want type - a lying resolver could mis-size or re-route the fill, redirecting or burning your payment)", ...base };
|
|
514
|
-
if (isTokenWant(offerRec.want) && (String(so?.want?.ticker) !== String(offerRec.want.ticker) || String(so?.want?.amount) !== String(offerRec.want.amount)))
|
|
515
|
-
return { ok: false, trust: "verified", reason: "the served want ticker/amount don't match the offer's on-chain record (a lying resolver could bait-and-switch the token price)", ...base };
|
|
517
|
+
return { ok: false, trust: "verified", reason: "the served terms don't match the offer's on-chain record (fee, rebate, partial sizing, the give, or the want's type or token price - a lying resolver could mis-size, re-price or re-route the fill, redirecting or burning your payment)", ...base };
|
|
516
518
|
}
|
|
517
519
|
if (sumsMismatch) return { ok: false, trust: "verified", reason: sumsMismatch, ...base };
|
|
518
520
|
return { ok: true, trust: "verified", ...base };
|
package/dist/react.cjs
CHANGED
|
@@ -26,7 +26,7 @@ __export(react_exports, {
|
|
|
26
26
|
module.exports = __toCommonJS(react_exports);
|
|
27
27
|
|
|
28
28
|
// src/errors.ts
|
|
29
|
-
var SDK_VERSION = "0.
|
|
29
|
+
var SDK_VERSION = "0.8.1";
|
|
30
30
|
var DOCS_BASE = "https://cairn-substrate.com/docs/sdk";
|
|
31
31
|
var CairnError = class extends Error {
|
|
32
32
|
/** Stable machine code for programmatic branching. */
|
package/dist/react.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CairnController
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-QWGR5J5D.js";
|
|
4
|
+
import "./chunk-F3KJPQXM.js";
|
|
5
|
+
import "./chunk-X7J6ECNV.js";
|
|
6
6
|
|
|
7
7
|
// src/react.ts
|
|
8
8
|
function createCairnHooks(React, controllerOrOpts) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inversealtruism/cairn-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "The Compute Substrate dApp kit: one cohesive toolkit to connect the Cairn Wallet, read the chain, the indexer and .csd names, verify self-certifying content, and resolve .csd names. Composes the published csd-* primitives.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -49,16 +49,16 @@
|
|
|
49
49
|
"README.md"
|
|
50
50
|
],
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@inversealtruism/cairnx-core": "0.2.
|
|
53
|
-
"@inversealtruism/csd-client": "0.1.
|
|
52
|
+
"@inversealtruism/cairnx-core": "0.2.3",
|
|
53
|
+
"@inversealtruism/csd-client": "0.1.20",
|
|
54
54
|
"@inversealtruism/csd-codec": "0.1.18",
|
|
55
|
-
"@inversealtruism/csd-crypto": "0.1.
|
|
56
|
-
"@inversealtruism/csd-light": "0.1.
|
|
57
|
-
"@inversealtruism/csd-tx": "0.1.
|
|
55
|
+
"@inversealtruism/csd-crypto": "0.1.20",
|
|
56
|
+
"@inversealtruism/csd-light": "0.1.26",
|
|
57
|
+
"@inversealtruism/csd-tx": "0.1.23"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@biomejs/biome": "2.5.15",
|
|
61
|
-
"@inversealtruism/csd-siwc": "0.1.
|
|
61
|
+
"@inversealtruism/csd-siwc": "0.1.21",
|
|
62
62
|
"@types/node": "22.19.20",
|
|
63
63
|
"esbuild": "0.28.2",
|
|
64
64
|
"playwright-core": "1.60.0",
|