@unicitylabs/sphere-sdk 0.14.9 → 0.14.11-dev.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/dist/connect/index.cjs +1 -1
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +1 -1
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +156 -22
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +2 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +156 -22
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +1 -1
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.js +1 -1
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/wallet-api-v2/index.cjs +4 -0
- package/dist/impl/wallet-api-v2/index.cjs.map +1 -1
- package/dist/impl/wallet-api-v2/index.js +4 -0
- package/dist/impl/wallet-api-v2/index.js.map +1 -1
- package/dist/index.cjs +156 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +156 -22
- package/dist/index.js.map +1 -1
- package/dist/modules/payments-v2/index.cjs +143 -16
- package/dist/modules/payments-v2/index.cjs.map +1 -1
- package/dist/modules/payments-v2/index.d.cts +6 -2
- package/dist/modules/payments-v2/index.d.ts +6 -2
- package/dist/modules/payments-v2/index.js +143 -16
- package/dist/modules/payments-v2/index.js.map +1 -1
- package/dist/token-engine/index.cjs +17 -6
- package/dist/token-engine/index.cjs.map +1 -1
- package/dist/token-engine/index.js +17 -6
- package/dist/token-engine/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -519,6 +519,10 @@ var import_StateMask = require("@unicitylabs/state-transition-sdk/lib/transactio
|
|
|
519
519
|
var import_MintJustificationVerifierService = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/MintJustificationVerifierService.js");
|
|
520
520
|
var import_TokenIssuanceVerifierService = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/TokenIssuanceVerifierService.js");
|
|
521
521
|
var import_VerificationContext = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/VerificationContext.js");
|
|
522
|
+
var import_UnicityCertificateVerifier = require("@unicitylabs/state-transition-sdk/lib/api/bft/verification/UnicityCertificateVerifier.js");
|
|
523
|
+
var import_UnicitySealQuorumSignaturesVerificationRule = require("@unicitylabs/state-transition-sdk/lib/api/bft/verification/rule/UnicitySealQuorumSignaturesVerificationRule.js");
|
|
524
|
+
var import_VerifiedSealCache = require("@unicitylabs/state-transition-sdk/lib/api/bft/verification/VerifiedSealCache.js");
|
|
525
|
+
var import_Secp256k1SignatureVerifier = require("@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/Secp256k1SignatureVerifier.js");
|
|
522
526
|
var import_WorkerTokenVerifier = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/worker/WorkerTokenVerifier.js");
|
|
523
527
|
var import_EncodedPredicate = require("@unicitylabs/state-transition-sdk/lib/predicate/EncodedPredicate.js");
|
|
524
528
|
var import_SignaturePredicate = require("@unicitylabs/state-transition-sdk/lib/predicate/builtin/SignaturePredicate.js");
|
|
@@ -1641,6 +1645,90 @@ async function splitOpIndex(deps, envelope) {
|
|
|
1641
1645
|
return Array.isArray(payload.direct) ? payload.direct.length : 0;
|
|
1642
1646
|
}
|
|
1643
1647
|
|
|
1648
|
+
// modules/payments-v2/mint-params.ts
|
|
1649
|
+
function mintParams(recipientPubkey, coinId, amount) {
|
|
1650
|
+
return { recipientPubkey, value: { assets: [{ coinId, amount }] } };
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
// modules/payments-v2/prewarm-cache.ts
|
|
1654
|
+
var PrewarmCache = class _PrewarmCache {
|
|
1655
|
+
entries = /* @__PURE__ */ new Map();
|
|
1656
|
+
generation = 0;
|
|
1657
|
+
static key(tokenId, stateHash) {
|
|
1658
|
+
return `${tokenId}:${stateHash}`;
|
|
1659
|
+
}
|
|
1660
|
+
/** Claim the cache for a warm about to start; supersedes any warm already running. */
|
|
1661
|
+
begin() {
|
|
1662
|
+
this.entries.clear();
|
|
1663
|
+
this.generation += 1;
|
|
1664
|
+
return this.generation;
|
|
1665
|
+
}
|
|
1666
|
+
/**
|
|
1667
|
+
* Publish a warm's result, unless it was cancelled or superseded while its
|
|
1668
|
+
* fetch was in flight — a cancel that only cleared what had landed so far
|
|
1669
|
+
* would be undone by the continuation of the very warm it cancelled.
|
|
1670
|
+
*/
|
|
1671
|
+
commit(generation, warmed) {
|
|
1672
|
+
if (generation !== this.generation) return;
|
|
1673
|
+
for (const [tokenId, stateHash, bytes] of warmed) {
|
|
1674
|
+
this.entries.set(_PrewarmCache.key(tokenId, stateHash), bytes);
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
get(tokenId, stateHash) {
|
|
1678
|
+
if (stateHash === void 0) return void 0;
|
|
1679
|
+
return this.entries.get(_PrewarmCache.key(tokenId, stateHash));
|
|
1680
|
+
}
|
|
1681
|
+
clear() {
|
|
1682
|
+
this.entries.clear();
|
|
1683
|
+
this.generation += 1;
|
|
1684
|
+
}
|
|
1685
|
+
get size() {
|
|
1686
|
+
return this.entries.size;
|
|
1687
|
+
}
|
|
1688
|
+
};
|
|
1689
|
+
async function warmSendSources(deps, request) {
|
|
1690
|
+
const ids = deps.queue.previewSelection(request);
|
|
1691
|
+
if (ids.length === 0) return;
|
|
1692
|
+
const generation = deps.cache.begin();
|
|
1693
|
+
const at = new Map(ids.map((id) => [id, deps.view.stateHashOf(id)]));
|
|
1694
|
+
let blobs;
|
|
1695
|
+
try {
|
|
1696
|
+
blobs = await deps.storagePort.getBlobs([...ids]);
|
|
1697
|
+
} catch {
|
|
1698
|
+
return;
|
|
1699
|
+
}
|
|
1700
|
+
const warmed = [];
|
|
1701
|
+
for (const [tokenId, bytes] of blobs) {
|
|
1702
|
+
const stateHash = at.get(tokenId);
|
|
1703
|
+
if (stateHash !== void 0) warmed.push([tokenId, stateHash, bytes]);
|
|
1704
|
+
}
|
|
1705
|
+
deps.cache.commit(generation, warmed);
|
|
1706
|
+
}
|
|
1707
|
+
async function takeSourceBlobs(deps, sourceIds) {
|
|
1708
|
+
const blobs = /* @__PURE__ */ new Map();
|
|
1709
|
+
const missing = [];
|
|
1710
|
+
let trustCache = deps.cache.size > 0;
|
|
1711
|
+
if (trustCache) {
|
|
1712
|
+
try {
|
|
1713
|
+
await deps.view.delta();
|
|
1714
|
+
} catch {
|
|
1715
|
+
trustCache = false;
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
for (const tokenId of sourceIds) {
|
|
1719
|
+
const warm = trustCache ? deps.cache.get(tokenId, deps.view.stateHashOf(tokenId)) : void 0;
|
|
1720
|
+
if (warm === void 0) missing.push(tokenId);
|
|
1721
|
+
else blobs.set(tokenId, warm);
|
|
1722
|
+
}
|
|
1723
|
+
deps.cache.clear();
|
|
1724
|
+
if (missing.length > 0) {
|
|
1725
|
+
for (const [tokenId, bytes] of await deps.storagePort.getBlobs(missing)) {
|
|
1726
|
+
blobs.set(tokenId, bytes);
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
return blobs;
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1644
1732
|
// modules/payments-v2/inventory/presentation.ts
|
|
1645
1733
|
function toToken(tokenId, snapshot, asset, registry, flags) {
|
|
1646
1734
|
const iconUrl = registry.getIconUrl(asset.coinId);
|
|
@@ -1727,6 +1815,13 @@ function priceOne(asset, quote) {
|
|
|
1727
1815
|
fiatValueEur: quote.priceEur != null ? human * quote.priceEur : null
|
|
1728
1816
|
};
|
|
1729
1817
|
}
|
|
1818
|
+
function transferringToken(tokenId, coinId, amount, registry, now) {
|
|
1819
|
+
const snapshot = { assets: [], createdAt: now, updatedAt: now };
|
|
1820
|
+
return toToken(tokenId, snapshot, { coinId, amount: amount.toString() }, registry, {
|
|
1821
|
+
transferring: true,
|
|
1822
|
+
suspectedSpent: false
|
|
1823
|
+
});
|
|
1824
|
+
}
|
|
1730
1825
|
|
|
1731
1826
|
// modules/payments-v2/machine/payload.ts
|
|
1732
1827
|
function buildPayload(recipientPubkey, request, spend, spentStates) {
|
|
@@ -2815,6 +2910,15 @@ var InventoryView = class {
|
|
|
2815
2910
|
}
|
|
2816
2911
|
return out;
|
|
2817
2912
|
}
|
|
2913
|
+
/**
|
|
2914
|
+
* Current mirrored state of an ACTIVE token, or undefined when it is unknown
|
|
2915
|
+
* or tombstoned. Exists so a cached blob can be state-scoped (F6): a blob is
|
|
2916
|
+
* only reusable while the token still sits at the state it was fetched at.
|
|
2917
|
+
*/
|
|
2918
|
+
stateHashOf(tokenId) {
|
|
2919
|
+
const entry = this.mirror.get(tokenId);
|
|
2920
|
+
return entry !== void 0 && entry.status === "active" ? entry.stateHash : void 0;
|
|
2921
|
+
}
|
|
2818
2922
|
tokens(registry, filter) {
|
|
2819
2923
|
const out = [];
|
|
2820
2924
|
for (const [tokenId, entry] of this.mirror) {
|
|
@@ -3826,6 +3930,31 @@ var SpendQueue = class {
|
|
|
3826
3930
|
}
|
|
3827
3931
|
return { kind: "queued", settled: this.enqueue(reservationId, request.coinId, amount) };
|
|
3828
3932
|
}
|
|
3933
|
+
/**
|
|
3934
|
+
* The sources `plan()` WOULD pick right now, reserving nothing and queueing
|
|
3935
|
+
* nothing — a read-only probe used to warm blobs while the user is still
|
|
3936
|
+
* looking at the confirm screen.
|
|
3937
|
+
*
|
|
3938
|
+
* Deliberately side-effect free: reserving here would pin the user's balance
|
|
3939
|
+
* across think-time and strand it if they never press send. The consequence is
|
|
3940
|
+
* that the real `plan()` may pick differently (inventory moves, another send
|
|
3941
|
+
* reserves first); callers must treat the result as a HINT and tolerate a miss,
|
|
3942
|
+
* never as a commitment that these sources will be spent.
|
|
3943
|
+
*/
|
|
3944
|
+
previewSelection(request) {
|
|
3945
|
+
if (this.destroyed) return [];
|
|
3946
|
+
let amount;
|
|
3947
|
+
try {
|
|
3948
|
+
amount = parseAmount(request.amount);
|
|
3949
|
+
} catch {
|
|
3950
|
+
return [];
|
|
3951
|
+
}
|
|
3952
|
+
const { freeView, freeTotal } = this.freeView(request.coinId);
|
|
3953
|
+
if (freeTotal < amount) return [];
|
|
3954
|
+
const plan = selectCoins(freeView, amount, { workBudget: this.deps.workBudget });
|
|
3955
|
+
if (plan === null) return [];
|
|
3956
|
+
return [...plan.direct, ...plan.split !== void 0 ? [plan.split.tokenId] : []];
|
|
3957
|
+
}
|
|
3829
3958
|
// Coverage math: free + Σ declared expected change of in-flight sends —
|
|
3830
3959
|
// never the full amount of in-flight sources (§5.3).
|
|
3831
3960
|
declareExpectedChange(transferId, coinId, amount) {
|
|
@@ -4175,6 +4304,7 @@ var PaymentsFacade = class {
|
|
|
4175
4304
|
now: () => this.nowMs()
|
|
4176
4305
|
});
|
|
4177
4306
|
}
|
|
4307
|
+
prewarmed = new PrewarmCache();
|
|
4178
4308
|
view;
|
|
4179
4309
|
ledger;
|
|
4180
4310
|
queue;
|
|
@@ -4268,6 +4398,15 @@ var PaymentsFacade = class {
|
|
|
4268
4398
|
return derivePendingTransfers(this.machineStores, this.machineDeps.decryptPayload);
|
|
4269
4399
|
}
|
|
4270
4400
|
// ── money movement ─────────────────────────────────────────────────────────
|
|
4401
|
+
async prewarmSend(request) {
|
|
4402
|
+
await warmSendSources(this.warmDeps(), request);
|
|
4403
|
+
}
|
|
4404
|
+
discardPrewarm() {
|
|
4405
|
+
this.prewarmed.clear();
|
|
4406
|
+
}
|
|
4407
|
+
warmDeps() {
|
|
4408
|
+
return { queue: this.queue, view: this.view, storagePort: this.deps.storagePort, cache: this.prewarmed };
|
|
4409
|
+
}
|
|
4271
4410
|
send(request) {
|
|
4272
4411
|
return this.track(this.sendOutcome(request));
|
|
4273
4412
|
}
|
|
@@ -4477,7 +4616,7 @@ var PaymentsFacade = class {
|
|
|
4477
4616
|
}
|
|
4478
4617
|
async materialize(transferId, recipientPubkey, request, spend, sourceIds) {
|
|
4479
4618
|
const engine = this.engine();
|
|
4480
|
-
const blobs = await this.
|
|
4619
|
+
const blobs = await takeSourceBlobs(this.warmDeps(), sourceIds);
|
|
4481
4620
|
const sources = /* @__PURE__ */ new Map();
|
|
4482
4621
|
const sourceTokens = [];
|
|
4483
4622
|
const spentStates = {};
|
|
@@ -4490,7 +4629,7 @@ var PaymentsFacade = class {
|
|
|
4490
4629
|
const keys = await engine.deliveryKeys(bytes);
|
|
4491
4630
|
spentStates[tokenId] = { local: keys.stateHash, protocol: keys.stateHash };
|
|
4492
4631
|
sources.set(tokenId, token);
|
|
4493
|
-
sourceTokens.push(
|
|
4632
|
+
sourceTokens.push(transferringToken(tokenId, request.coinId, engine.balanceOf(token, request.coinId), this.deps.registry, this.nowMs()));
|
|
4494
4633
|
}
|
|
4495
4634
|
const payload = buildPayload(recipientPubkey, request, spend, spentStates);
|
|
4496
4635
|
const plan = {
|
|
@@ -4634,7 +4773,7 @@ var PaymentsFacade = class {
|
|
|
4634
4773
|
await this.machineStores.mintJournal.upsert(entry);
|
|
4635
4774
|
let token;
|
|
4636
4775
|
try {
|
|
4637
|
-
token = await engine.mint(this.
|
|
4776
|
+
token = await engine.mint(mintParams(this.ownPubkeyBytes, coinId, amount), { transferId: mintId });
|
|
4638
4777
|
} catch (err) {
|
|
4639
4778
|
this.heartbeat.arm();
|
|
4640
4779
|
return { success: false, error: messageOf(err) };
|
|
@@ -4693,7 +4832,7 @@ var PaymentsFacade = class {
|
|
|
4693
4832
|
});
|
|
4694
4833
|
return false;
|
|
4695
4834
|
}
|
|
4696
|
-
const token = await engine.mint(this.
|
|
4835
|
+
const token = await engine.mint(mintParams(this.ownPubkeyBytes, entry.coinId, BigInt(entry.amount)), {
|
|
4697
4836
|
transferId: entry.mintId
|
|
4698
4837
|
});
|
|
4699
4838
|
if (token.blob.tokenId !== entry.tokenId) {
|
|
@@ -4702,12 +4841,6 @@ var PaymentsFacade = class {
|
|
|
4702
4841
|
await this.finalizeMint(engine, entry.mintId, token, entry.coinId, entry.amount);
|
|
4703
4842
|
return true;
|
|
4704
4843
|
}
|
|
4705
|
-
mintParams(coinId, amount) {
|
|
4706
|
-
return {
|
|
4707
|
-
recipientPubkey: this.ownPubkeyBytes,
|
|
4708
|
-
value: { assets: [{ coinId, amount }] }
|
|
4709
|
-
};
|
|
4710
|
-
}
|
|
4711
4844
|
async tokenInServerInventory(tokenId) {
|
|
4712
4845
|
let page = await this.deps.storagePort.listInventory();
|
|
4713
4846
|
for (let i = 0; i < INVENTORY_SCAN_PAGE_LIMIT; i++) {
|
|
@@ -4736,12 +4869,6 @@ var PaymentsFacade = class {
|
|
|
4736
4869
|
page = await this.deps.storagePort.listInventory(page.cursor);
|
|
4737
4870
|
}
|
|
4738
4871
|
}
|
|
4739
|
-
toUiToken(tokenId, coinId, amount) {
|
|
4740
|
-
const now = this.nowMs();
|
|
4741
|
-
const snapshot = { assets: [], createdAt: now, updatedAt: now };
|
|
4742
|
-
const flags = { transferring: true, suspectedSpent: false };
|
|
4743
|
-
return toToken(tokenId, snapshot, { coinId, amount: amount.toString() }, this.deps.registry, flags);
|
|
4744
|
-
}
|
|
4745
4872
|
track(op) {
|
|
4746
4873
|
const settled = op.then(() => void 0, () => void 0);
|
|
4747
4874
|
this.pendingOps.add(settled);
|