@unicitylabs/sphere-sdk 0.17.0 → 0.17.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 +170 -141
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +4 -2
- package/dist/core/index.d.ts +4 -2
- package/dist/core/index.js +170 -141
- 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/index.cjs +170 -141
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +170 -141
- package/dist/index.js.map +1 -1
- package/dist/modules/payments-v2/index.cjs +243 -214
- package/dist/modules/payments-v2/index.cjs.map +1 -1
- package/dist/modules/payments-v2/index.d.cts +13 -11
- package/dist/modules/payments-v2/index.d.ts +13 -11
- package/dist/modules/payments-v2/index.js +243 -214
- package/dist/modules/payments-v2/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -832,71 +832,15 @@ function createMachineStores(kv) {
|
|
|
832
832
|
};
|
|
833
833
|
}
|
|
834
834
|
|
|
835
|
-
//
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
var import_JsonRpcNetworkError = require("@unicitylabs/state-transition-sdk/lib/api/json-rpc/JsonRpcNetworkError.js");
|
|
845
|
-
var import_RootTrustBase = require("@unicitylabs/state-transition-sdk/lib/api/bft/RootTrustBase.js");
|
|
846
|
-
var import_InclusionProofUtils = require("@unicitylabs/state-transition-sdk/lib/util/InclusionProofUtils.js");
|
|
847
|
-
var import_InclusionProofVerificationRule = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/rule/InclusionProofVerificationRule.js");
|
|
848
|
-
var import_Token = require("@unicitylabs/state-transition-sdk/lib/transaction/Token.js");
|
|
849
|
-
var import_MintTransaction = require("@unicitylabs/state-transition-sdk/lib/transaction/MintTransaction.js");
|
|
850
|
-
var import_TransferTransaction = require("@unicitylabs/state-transition-sdk/lib/transaction/TransferTransaction.js");
|
|
851
|
-
var import_CertifiedMintTransaction = require("@unicitylabs/state-transition-sdk/lib/transaction/CertifiedMintTransaction.js");
|
|
852
|
-
var import_CertifiedTransferTransaction = require("@unicitylabs/state-transition-sdk/lib/transaction/CertifiedTransferTransaction.js");
|
|
853
|
-
var import_TokenId = require("@unicitylabs/state-transition-sdk/lib/transaction/TokenId.js");
|
|
854
|
-
var import_TokenType = require("@unicitylabs/state-transition-sdk/lib/transaction/TokenType.js");
|
|
855
|
-
var import_TokenSalt = require("@unicitylabs/state-transition-sdk/lib/transaction/TokenSalt.js");
|
|
856
|
-
var import_StateMask = require("@unicitylabs/state-transition-sdk/lib/transaction/StateMask.js");
|
|
857
|
-
var import_MintJustificationVerifierService = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/MintJustificationVerifierService.js");
|
|
858
|
-
var import_TokenIssuanceVerifierService = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/TokenIssuanceVerifierService.js");
|
|
859
|
-
var import_VerificationContext = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/VerificationContext.js");
|
|
860
|
-
var import_UnicityCertificateVerifier = require("@unicitylabs/state-transition-sdk/lib/api/bft/verification/UnicityCertificateVerifier.js");
|
|
861
|
-
var import_UnicitySealQuorumSignaturesVerificationRule = require("@unicitylabs/state-transition-sdk/lib/api/bft/verification/rule/UnicitySealQuorumSignaturesVerificationRule.js");
|
|
862
|
-
var import_VerifiedSealCache = require("@unicitylabs/state-transition-sdk/lib/api/bft/verification/VerifiedSealCache.js");
|
|
863
|
-
var import_Secp256k1SignatureVerifier = require("@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/Secp256k1SignatureVerifier.js");
|
|
864
|
-
var import_WorkerTokenVerifier = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/worker/WorkerTokenVerifier.js");
|
|
865
|
-
var import_EncodedPredicate = require("@unicitylabs/state-transition-sdk/lib/predicate/EncodedPredicate.js");
|
|
866
|
-
var import_SignaturePredicate = require("@unicitylabs/state-transition-sdk/lib/predicate/builtin/SignaturePredicate.js");
|
|
867
|
-
var import_SignaturePredicateUnlockScript = require("@unicitylabs/state-transition-sdk/lib/predicate/builtin/SignaturePredicateUnlockScript.js");
|
|
868
|
-
var import_BurnPredicate = require("@unicitylabs/state-transition-sdk/lib/predicate/builtin/BurnPredicate.js");
|
|
869
|
-
var import_PredicateVerifierService = require("@unicitylabs/state-transition-sdk/lib/predicate/verification/PredicateVerifierService.js");
|
|
870
|
-
var import_SigningService = require("@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/SigningService.js");
|
|
871
|
-
var import_Signature = require("@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/Signature.js");
|
|
872
|
-
var import_MintSigningService = require("@unicitylabs/state-transition-sdk/lib/crypto/MintSigningService.js");
|
|
873
|
-
var import_HashAlgorithm = require("@unicitylabs/state-transition-sdk/lib/crypto/hash/HashAlgorithm.js");
|
|
874
|
-
var import_DataHash = require("@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHash.js");
|
|
875
|
-
var import_DataHasher = require("@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHasher.js");
|
|
876
|
-
var import_DataHasherFactory = require("@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHasherFactory.js");
|
|
877
|
-
var import_CborSerializer = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborSerializer.js");
|
|
878
|
-
var import_CborDeserializer = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborDeserializer.js");
|
|
879
|
-
var import_CborError = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborError.js");
|
|
880
|
-
var import_CborReader = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborReader.js");
|
|
881
|
-
var import_MajorType = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/MajorType.js");
|
|
882
|
-
var import_Asset = require("@unicitylabs/state-transition-sdk/lib/payment/asset/Asset.js");
|
|
883
|
-
var import_AssetId = require("@unicitylabs/state-transition-sdk/lib/payment/asset/AssetId.js");
|
|
884
|
-
var import_PaymentAssetCollection = require("@unicitylabs/state-transition-sdk/lib/payment/asset/PaymentAssetCollection.js");
|
|
885
|
-
var import_TokenSplit = require("@unicitylabs/state-transition-sdk/lib/payment/TokenSplit.js");
|
|
886
|
-
var import_SplitTokenRequest = require("@unicitylabs/state-transition-sdk/lib/payment/SplitTokenRequest.js");
|
|
887
|
-
var import_SplitToken = require("@unicitylabs/state-transition-sdk/lib/payment/SplitToken.js");
|
|
888
|
-
var import_SplitAllocationProof = require("@unicitylabs/state-transition-sdk/lib/payment/SplitAllocationProof.js");
|
|
889
|
-
var import_SplitMintJustification = require("@unicitylabs/state-transition-sdk/lib/payment/SplitMintJustification.js");
|
|
890
|
-
var import_SplitMintJustificationVerifier = require("@unicitylabs/state-transition-sdk/lib/payment/SplitMintJustificationVerifier.js");
|
|
891
|
-
var import_VerificationStatus = require("@unicitylabs/state-transition-sdk/lib/verification/VerificationStatus.js");
|
|
892
|
-
var import_VerificationResult = require("@unicitylabs/state-transition-sdk/lib/verification/VerificationResult.js");
|
|
893
|
-
var import_HexConverter = require("@unicitylabs/state-transition-sdk/lib/util/HexConverter.js");
|
|
894
|
-
var import_BigintConverter = require("@unicitylabs/state-transition-sdk/lib/util/BigintConverter.js");
|
|
895
|
-
var import_BitString = require("@unicitylabs/state-transition-sdk/lib/util/BitString.js");
|
|
896
|
-
|
|
897
|
-
// token-engine/value-envelope.ts
|
|
898
|
-
function isCoinlessEnvelope(envelope) {
|
|
899
|
-
return envelope.startsWith("none_");
|
|
835
|
+
// modules/payments-v2/machine/payload-view.ts
|
|
836
|
+
function isWholeIntent(p) {
|
|
837
|
+
return p.kind === "whole" || p.kind === "coinless";
|
|
838
|
+
}
|
|
839
|
+
function splitOf(p) {
|
|
840
|
+
return p.kind === "coin" ? p.split : void 0;
|
|
841
|
+
}
|
|
842
|
+
function coinIdOf(p) {
|
|
843
|
+
return p.kind === "coin" ? p.coinId : void 0;
|
|
900
844
|
}
|
|
901
845
|
|
|
902
846
|
// token-engine/errors.ts
|
|
@@ -938,14 +882,6 @@ var CheckpointTrustbaseMismatchError = class extends SphereError {
|
|
|
938
882
|
}
|
|
939
883
|
};
|
|
940
884
|
|
|
941
|
-
// modules/payments-v2/machine/payload-view.ts
|
|
942
|
-
function splitOf(p) {
|
|
943
|
-
return p.kind === "coin" ? p.split : void 0;
|
|
944
|
-
}
|
|
945
|
-
function coinIdOf(p) {
|
|
946
|
-
return p.kind === "coin" ? p.coinId : void 0;
|
|
947
|
-
}
|
|
948
|
-
|
|
949
885
|
// modules/payments-v2/machine/TransferMachine.ts
|
|
950
886
|
var CERTIFY_WIDTH = 20;
|
|
951
887
|
var KEEP_OPEN_CODES = /* @__PURE__ */ new Set([
|
|
@@ -1307,7 +1243,14 @@ var TransferMachine = class {
|
|
|
1307
1243
|
try {
|
|
1308
1244
|
const coinId = coinIdOf(payload);
|
|
1309
1245
|
const committedAmount = coinId === void 0 ? "0" : await this.settledAmount(engine, coinId, committed);
|
|
1310
|
-
await this.
|
|
1246
|
+
const committedAssets = coinId === void 0 ? await this.settledAssets(engine, committed) : void 0;
|
|
1247
|
+
await this.deps.recordHistory?.({
|
|
1248
|
+
transferId,
|
|
1249
|
+
payload,
|
|
1250
|
+
phase,
|
|
1251
|
+
committedAmount,
|
|
1252
|
+
...committedAssets !== void 0 ? { committedAssets } : {}
|
|
1253
|
+
});
|
|
1311
1254
|
} catch {
|
|
1312
1255
|
}
|
|
1313
1256
|
try {
|
|
@@ -1321,6 +1264,18 @@ var TransferMachine = class {
|
|
|
1321
1264
|
* a journal-rehydrated resume leg has no source token, but every committed
|
|
1322
1265
|
* leg carries its recipient blob, so the outcome-derived rule is uniform).
|
|
1323
1266
|
*/
|
|
1267
|
+
/** Every asset across the certified recipient blobs — the whole-spend twin of settledAmount. */
|
|
1268
|
+
async settledAssets(engine, committed) {
|
|
1269
|
+
const total = /* @__PURE__ */ new Map();
|
|
1270
|
+
for (const outcome of committed) {
|
|
1271
|
+
if (outcome.recipientBlob === void 0) continue;
|
|
1272
|
+
const token = await engine.decodeToken({ tokenId: "", token: outcome.recipientBlob });
|
|
1273
|
+
for (const asset of engine.readValue(token)?.assets ?? []) {
|
|
1274
|
+
total.set(asset.coinId, (total.get(asset.coinId) ?? 0n) + asset.amount);
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
return [...total].map(([coinId, amount]) => ({ coinId, amount: amount.toString() }));
|
|
1278
|
+
}
|
|
1324
1279
|
async settledAmount(engine, coinId, committed) {
|
|
1325
1280
|
let total = 0n;
|
|
1326
1281
|
for (const outcome of committed) {
|
|
@@ -1460,7 +1415,7 @@ async function runOne(ctx, job, report) {
|
|
|
1460
1415
|
report.failed.push(job.transferId);
|
|
1461
1416
|
return;
|
|
1462
1417
|
}
|
|
1463
|
-
if (job.payload.
|
|
1418
|
+
if (isWholeIntent(job.payload) && token.valueEnvelope === "bare_collection") {
|
|
1464
1419
|
logger.warn(
|
|
1465
1420
|
"PaymentsV2",
|
|
1466
1421
|
`resume: token intent ${job.transferId} names a source carrying coin value \u2014 refusing`
|
|
@@ -1508,7 +1463,7 @@ function validateCoinPayload(c) {
|
|
|
1508
1463
|
}
|
|
1509
1464
|
return { ...c, kind: "coin" };
|
|
1510
1465
|
}
|
|
1511
|
-
function
|
|
1466
|
+
function validateWholePayload(p) {
|
|
1512
1467
|
if (p.direct?.length !== 1 || typeof p.direct[0] !== "string" || p.direct[0] === "") {
|
|
1513
1468
|
throw new SphereError(
|
|
1514
1469
|
"token intent payload must name exactly one source token",
|
|
@@ -1518,7 +1473,7 @@ function validateCoinlessPayload(p) {
|
|
|
1518
1473
|
if (p.split !== void 0) {
|
|
1519
1474
|
throw new SphereError("token intent payload cannot carry a split", "VALIDATION_ERROR");
|
|
1520
1475
|
}
|
|
1521
|
-
return { ...p, kind: "
|
|
1476
|
+
return { ...p, kind: "whole", direct: [p.direct[0]] };
|
|
1522
1477
|
}
|
|
1523
1478
|
function validatePayload(raw) {
|
|
1524
1479
|
const p = raw !== null && typeof raw === "object" ? raw : null;
|
|
@@ -1532,13 +1487,13 @@ function validatePayload(raw) {
|
|
|
1532
1487
|
throw new SphereError("intent payload is missing recipient", "VALIDATION_ERROR");
|
|
1533
1488
|
}
|
|
1534
1489
|
const kind = p.kind ?? "coin";
|
|
1535
|
-
if (kind !== "coin" && kind !== "coinless") {
|
|
1490
|
+
if (kind !== "coin" && kind !== "whole" && kind !== "coinless") {
|
|
1536
1491
|
throw new SphereError(
|
|
1537
1492
|
`unsupported intent kind '${String(kind)}' \u2014 not resumable by this client`,
|
|
1538
1493
|
"VALIDATION_ERROR"
|
|
1539
1494
|
);
|
|
1540
1495
|
}
|
|
1541
|
-
return kind === "
|
|
1496
|
+
return kind === "coin" ? validateCoinPayload(p) : validateWholePayload(p);
|
|
1542
1497
|
}
|
|
1543
1498
|
|
|
1544
1499
|
// modules/payments-v2/convergence.ts
|
|
@@ -1751,8 +1706,9 @@ async function openRow(entry, journal, decryptPayload) {
|
|
|
1751
1706
|
};
|
|
1752
1707
|
}
|
|
1753
1708
|
function subject(payload) {
|
|
1754
|
-
|
|
1755
|
-
|
|
1709
|
+
const rawKind = payload?.kind;
|
|
1710
|
+
if (rawKind === "whole" || rawKind === "coinless") {
|
|
1711
|
+
const tokenId = payload?.direct?.[0];
|
|
1756
1712
|
return { coinId: "", amount: "", ...typeof tokenId === "string" ? { tokenId } : {} };
|
|
1757
1713
|
}
|
|
1758
1714
|
const coin = payload;
|
|
@@ -1825,10 +1781,10 @@ function buildPayload(recipientPubkey, request, spend, spentStates) {
|
|
|
1825
1781
|
function messageOf(err) {
|
|
1826
1782
|
return err instanceof Error ? err.message : String(err);
|
|
1827
1783
|
}
|
|
1828
|
-
function
|
|
1784
|
+
function buildWholePayload(recipientPubkey, request, spentStates) {
|
|
1829
1785
|
return {
|
|
1830
1786
|
v: 2,
|
|
1831
|
-
kind: "
|
|
1787
|
+
kind: "whole",
|
|
1832
1788
|
recipient: recipientPubkey,
|
|
1833
1789
|
...request.memo !== void 0 ? { memo: request.memo } : {},
|
|
1834
1790
|
direct: [request.tokenId],
|
|
@@ -1897,8 +1853,102 @@ async function finalizeMint(deps, mintId, token, coinId, amount) {
|
|
|
1897
1853
|
deps.refreshView();
|
|
1898
1854
|
}
|
|
1899
1855
|
|
|
1900
|
-
// modules/payments-v2/
|
|
1901
|
-
|
|
1856
|
+
// modules/payments-v2/inventory/presentation.ts
|
|
1857
|
+
function toToken(tokenId, snapshot, asset, registry, flags) {
|
|
1858
|
+
const iconUrl = registry.getIconUrl(asset.coinId);
|
|
1859
|
+
return {
|
|
1860
|
+
id: tokenId,
|
|
1861
|
+
coinId: asset.coinId,
|
|
1862
|
+
symbol: registry.getSymbol(asset.coinId),
|
|
1863
|
+
name: registry.getName(asset.coinId),
|
|
1864
|
+
decimals: registry.getDecimals(asset.coinId),
|
|
1865
|
+
...iconUrl !== null ? { iconUrl } : {},
|
|
1866
|
+
amount: asset.amount,
|
|
1867
|
+
status: flags.transferring ? "transferring" : "confirmed",
|
|
1868
|
+
createdAt: snapshot.createdAt,
|
|
1869
|
+
updatedAt: snapshot.updatedAt,
|
|
1870
|
+
lazy: true,
|
|
1871
|
+
...flags.suspectedSpent ? { suspectedSpent: true } : {}
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1874
|
+
function aggregateAssets(entries, isTransferring, registry) {
|
|
1875
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1876
|
+
for (const [tokenId, entry] of entries) {
|
|
1877
|
+
const moving = isTransferring(tokenId);
|
|
1878
|
+
for (const asset of entry.assets) {
|
|
1879
|
+
let group = groups.get(asset.coinId);
|
|
1880
|
+
if (!group) {
|
|
1881
|
+
group = { total: 0n, count: 0, transferring: 0n, transferringCount: 0 };
|
|
1882
|
+
groups.set(asset.coinId, group);
|
|
1883
|
+
}
|
|
1884
|
+
if (moving) {
|
|
1885
|
+
group.transferring += BigInt(asset.amount);
|
|
1886
|
+
group.transferringCount += 1;
|
|
1887
|
+
} else {
|
|
1888
|
+
group.total += BigInt(asset.amount);
|
|
1889
|
+
group.count += 1;
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
return [...groups].map(([coinId, totals]) => toAsset(coinId, totals, registry));
|
|
1894
|
+
}
|
|
1895
|
+
function toAsset(coinId, totals, registry) {
|
|
1896
|
+
const iconUrl = registry.getIconUrl(coinId);
|
|
1897
|
+
return {
|
|
1898
|
+
coinId,
|
|
1899
|
+
symbol: registry.getSymbol(coinId),
|
|
1900
|
+
name: registry.getName(coinId),
|
|
1901
|
+
decimals: registry.getDecimals(coinId),
|
|
1902
|
+
...iconUrl !== null ? { iconUrl } : {},
|
|
1903
|
+
totalAmount: totals.total.toString(),
|
|
1904
|
+
tokenCount: totals.count,
|
|
1905
|
+
confirmedAmount: totals.total.toString(),
|
|
1906
|
+
unconfirmedAmount: "0",
|
|
1907
|
+
confirmedTokenCount: totals.count,
|
|
1908
|
+
unconfirmedTokenCount: 0,
|
|
1909
|
+
transferringTokenCount: totals.transferringCount,
|
|
1910
|
+
transferringAmount: totals.transferring.toString(),
|
|
1911
|
+
priceUsd: null,
|
|
1912
|
+
priceEur: null,
|
|
1913
|
+
change24h: null,
|
|
1914
|
+
fiatValueUsd: null,
|
|
1915
|
+
fiatValueEur: null
|
|
1916
|
+
};
|
|
1917
|
+
}
|
|
1918
|
+
function priceIdOf(registry, coinId) {
|
|
1919
|
+
return registry.getName(coinId).toLowerCase();
|
|
1920
|
+
}
|
|
1921
|
+
async function withPrices(raw, registry, price) {
|
|
1922
|
+
try {
|
|
1923
|
+
const ids = [...new Set(raw.map((a) => priceIdOf(registry, a.coinId)))];
|
|
1924
|
+
const quotes = await price.getPrices(ids);
|
|
1925
|
+
return raw.map((a) => priceOne(a, quotes.get(priceIdOf(registry, a.coinId))));
|
|
1926
|
+
} catch {
|
|
1927
|
+
return raw;
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
function priceOne(asset, quote) {
|
|
1931
|
+
if (!quote) return asset;
|
|
1932
|
+
const human = Number(asset.totalAmount) / Math.pow(10, asset.decimals);
|
|
1933
|
+
return {
|
|
1934
|
+
...asset,
|
|
1935
|
+
priceUsd: quote.priceUsd,
|
|
1936
|
+
priceEur: quote.priceEur ?? null,
|
|
1937
|
+
change24h: quote.change24h ?? null,
|
|
1938
|
+
fiatValueUsd: human * quote.priceUsd,
|
|
1939
|
+
fiatValueEur: quote.priceEur != null ? human * quote.priceEur : null
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
function transferringToken(tokenId, coinId, amount, registry, now) {
|
|
1943
|
+
const snapshot = { assets: [], createdAt: now, updatedAt: now };
|
|
1944
|
+
return toToken(tokenId, snapshot, { coinId, amount: amount.toString() }, registry, {
|
|
1945
|
+
transferring: true,
|
|
1946
|
+
suspectedSpent: false
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
// modules/payments-v2/send-whole.ts
|
|
1951
|
+
async function materializeWholeSpend(deps, input) {
|
|
1902
1952
|
const { engine } = deps;
|
|
1903
1953
|
const tokenId = input.request.tokenId;
|
|
1904
1954
|
const bytes = (await deps.storagePort.getBlobs([tokenId])).get(tokenId);
|
|
@@ -1906,14 +1956,20 @@ async function materializeCoinlessSpend(deps, input) {
|
|
|
1906
1956
|
throw new SphereError(`Selected source ${tokenId} has no blob in storage`, "STORAGE_ERROR");
|
|
1907
1957
|
}
|
|
1908
1958
|
const token = await engine.decodeToken({ tokenId, token: bytes });
|
|
1909
|
-
if (
|
|
1959
|
+
if (token.valueEnvelope === "bare_collection") {
|
|
1960
|
+
throw new SphereError(
|
|
1961
|
+
`Token ${tokenId} carries a value envelope this SDK cannot read, so its coins cannot be accounted for; it cannot be sent`,
|
|
1962
|
+
"VALIDATION_ERROR"
|
|
1963
|
+
);
|
|
1964
|
+
}
|
|
1965
|
+
if (input.requireCoinless && token.value !== null) {
|
|
1910
1966
|
throw new SphereError(
|
|
1911
|
-
`Token ${tokenId} carries coin value and cannot be sent with sendCoinless \u2014 use
|
|
1967
|
+
`Token ${tokenId} carries coin value and cannot be sent with sendCoinless \u2014 use sendWholeToken, which requires coin-transfer authority`,
|
|
1912
1968
|
"VALIDATION_ERROR"
|
|
1913
1969
|
);
|
|
1914
1970
|
}
|
|
1915
1971
|
const keys = await engine.deliveryKeys(bytes);
|
|
1916
|
-
const payload =
|
|
1972
|
+
const payload = buildWholePayload(input.recipientPubkey, input.request, {
|
|
1917
1973
|
[tokenId]: { local: keys.stateHash, protocol: keys.stateHash }
|
|
1918
1974
|
});
|
|
1919
1975
|
const plan = {
|
|
@@ -1924,7 +1980,10 @@ async function materializeCoinlessSpend(deps, input) {
|
|
|
1924
1980
|
sources: /* @__PURE__ */ new Map([[tokenId, token]]),
|
|
1925
1981
|
...input.request.memo !== void 0 ? { memo: input.request.memo } : {}
|
|
1926
1982
|
};
|
|
1927
|
-
|
|
1983
|
+
const sourceTokens = (token.value?.assets ?? []).map(
|
|
1984
|
+
(asset) => transferringToken(tokenId, asset.coinId, asset.amount, deps.registry, deps.now)
|
|
1985
|
+
);
|
|
1986
|
+
return { transferId: input.transferId, coinId: "", plan, sourceIds: input.sourceIds, sourceTokens };
|
|
1928
1987
|
}
|
|
1929
1988
|
|
|
1930
1989
|
// modules/payments-v2/send-errors.ts
|
|
@@ -2071,100 +2130,6 @@ async function takeSourceBlobs(deps, sourceIds) {
|
|
|
2071
2130
|
return blobs;
|
|
2072
2131
|
}
|
|
2073
2132
|
|
|
2074
|
-
// modules/payments-v2/inventory/presentation.ts
|
|
2075
|
-
function toToken(tokenId, snapshot, asset, registry, flags) {
|
|
2076
|
-
const iconUrl = registry.getIconUrl(asset.coinId);
|
|
2077
|
-
return {
|
|
2078
|
-
id: tokenId,
|
|
2079
|
-
coinId: asset.coinId,
|
|
2080
|
-
symbol: registry.getSymbol(asset.coinId),
|
|
2081
|
-
name: registry.getName(asset.coinId),
|
|
2082
|
-
decimals: registry.getDecimals(asset.coinId),
|
|
2083
|
-
...iconUrl !== null ? { iconUrl } : {},
|
|
2084
|
-
amount: asset.amount,
|
|
2085
|
-
status: flags.transferring ? "transferring" : "confirmed",
|
|
2086
|
-
createdAt: snapshot.createdAt,
|
|
2087
|
-
updatedAt: snapshot.updatedAt,
|
|
2088
|
-
lazy: true,
|
|
2089
|
-
...flags.suspectedSpent ? { suspectedSpent: true } : {}
|
|
2090
|
-
};
|
|
2091
|
-
}
|
|
2092
|
-
function aggregateAssets(entries, isTransferring, registry) {
|
|
2093
|
-
const groups = /* @__PURE__ */ new Map();
|
|
2094
|
-
for (const [tokenId, entry] of entries) {
|
|
2095
|
-
const moving = isTransferring(tokenId);
|
|
2096
|
-
for (const asset of entry.assets) {
|
|
2097
|
-
let group = groups.get(asset.coinId);
|
|
2098
|
-
if (!group) {
|
|
2099
|
-
group = { total: 0n, count: 0, transferring: 0n, transferringCount: 0 };
|
|
2100
|
-
groups.set(asset.coinId, group);
|
|
2101
|
-
}
|
|
2102
|
-
if (moving) {
|
|
2103
|
-
group.transferring += BigInt(asset.amount);
|
|
2104
|
-
group.transferringCount += 1;
|
|
2105
|
-
} else {
|
|
2106
|
-
group.total += BigInt(asset.amount);
|
|
2107
|
-
group.count += 1;
|
|
2108
|
-
}
|
|
2109
|
-
}
|
|
2110
|
-
}
|
|
2111
|
-
return [...groups].map(([coinId, totals]) => toAsset(coinId, totals, registry));
|
|
2112
|
-
}
|
|
2113
|
-
function toAsset(coinId, totals, registry) {
|
|
2114
|
-
const iconUrl = registry.getIconUrl(coinId);
|
|
2115
|
-
return {
|
|
2116
|
-
coinId,
|
|
2117
|
-
symbol: registry.getSymbol(coinId),
|
|
2118
|
-
name: registry.getName(coinId),
|
|
2119
|
-
decimals: registry.getDecimals(coinId),
|
|
2120
|
-
...iconUrl !== null ? { iconUrl } : {},
|
|
2121
|
-
totalAmount: totals.total.toString(),
|
|
2122
|
-
tokenCount: totals.count,
|
|
2123
|
-
confirmedAmount: totals.total.toString(),
|
|
2124
|
-
unconfirmedAmount: "0",
|
|
2125
|
-
confirmedTokenCount: totals.count,
|
|
2126
|
-
unconfirmedTokenCount: 0,
|
|
2127
|
-
transferringTokenCount: totals.transferringCount,
|
|
2128
|
-
transferringAmount: totals.transferring.toString(),
|
|
2129
|
-
priceUsd: null,
|
|
2130
|
-
priceEur: null,
|
|
2131
|
-
change24h: null,
|
|
2132
|
-
fiatValueUsd: null,
|
|
2133
|
-
fiatValueEur: null
|
|
2134
|
-
};
|
|
2135
|
-
}
|
|
2136
|
-
function priceIdOf(registry, coinId) {
|
|
2137
|
-
return registry.getName(coinId).toLowerCase();
|
|
2138
|
-
}
|
|
2139
|
-
async function withPrices(raw, registry, price) {
|
|
2140
|
-
try {
|
|
2141
|
-
const ids = [...new Set(raw.map((a) => priceIdOf(registry, a.coinId)))];
|
|
2142
|
-
const quotes = await price.getPrices(ids);
|
|
2143
|
-
return raw.map((a) => priceOne(a, quotes.get(priceIdOf(registry, a.coinId))));
|
|
2144
|
-
} catch {
|
|
2145
|
-
return raw;
|
|
2146
|
-
}
|
|
2147
|
-
}
|
|
2148
|
-
function priceOne(asset, quote) {
|
|
2149
|
-
if (!quote) return asset;
|
|
2150
|
-
const human = Number(asset.totalAmount) / Math.pow(10, asset.decimals);
|
|
2151
|
-
return {
|
|
2152
|
-
...asset,
|
|
2153
|
-
priceUsd: quote.priceUsd,
|
|
2154
|
-
priceEur: quote.priceEur ?? null,
|
|
2155
|
-
change24h: quote.change24h ?? null,
|
|
2156
|
-
fiatValueUsd: human * quote.priceUsd,
|
|
2157
|
-
fiatValueEur: quote.priceEur != null ? human * quote.priceEur : null
|
|
2158
|
-
};
|
|
2159
|
-
}
|
|
2160
|
-
function transferringToken(tokenId, coinId, amount, registry, now) {
|
|
2161
|
-
const snapshot = { assets: [], createdAt: now, updatedAt: now };
|
|
2162
|
-
return toToken(tokenId, snapshot, { coinId, amount: amount.toString() }, registry, {
|
|
2163
|
-
transferring: true,
|
|
2164
|
-
suspectedSpent: false
|
|
2165
|
-
});
|
|
2166
|
-
}
|
|
2167
|
-
|
|
2168
2133
|
// node_modules/@noble/ciphers/utils.js
|
|
2169
2134
|
function isBytes2(a) {
|
|
2170
2135
|
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
@@ -3270,10 +3235,10 @@ var InventoryView = class {
|
|
|
3270
3235
|
if (this.inFlight.has(tokenId) && !this.pinned(tokenId)) return false;
|
|
3271
3236
|
return !this.suspected.has(stateKey(tokenId, entry.stateHash));
|
|
3272
3237
|
}
|
|
3273
|
-
/**
|
|
3274
|
-
|
|
3238
|
+
/** Is this NAMED token spendable whole — coinless or valued (#777)? */
|
|
3239
|
+
spendableToken(tokenId) {
|
|
3275
3240
|
const entry = this.mirror.get(tokenId);
|
|
3276
|
-
return entry !== void 0 &&
|
|
3241
|
+
return entry !== void 0 && this.isSpendable(tokenId, entry);
|
|
3277
3242
|
}
|
|
3278
3243
|
/**
|
|
3279
3244
|
* Current mirrored state of an ACTIVE token, or undefined when it is unknown
|
|
@@ -3497,6 +3462,73 @@ var InventoryView = class {
|
|
|
3497
3462
|
}
|
|
3498
3463
|
};
|
|
3499
3464
|
|
|
3465
|
+
// token-engine/sdk.ts
|
|
3466
|
+
var import_StateTransitionClient = require("@unicitylabs/state-transition-sdk/lib/StateTransitionClient.js");
|
|
3467
|
+
var import_AggregatorClient = require("@unicitylabs/state-transition-sdk/lib/api/AggregatorClient.js");
|
|
3468
|
+
var import_NetworkId = require("@unicitylabs/state-transition-sdk/lib/api/NetworkId.js");
|
|
3469
|
+
var import_CertificationData = require("@unicitylabs/state-transition-sdk/lib/api/CertificationData.js");
|
|
3470
|
+
var import_CertificationResponse = require("@unicitylabs/state-transition-sdk/lib/api/CertificationResponse.js");
|
|
3471
|
+
var import_StateId = require("@unicitylabs/state-transition-sdk/lib/api/StateId.js");
|
|
3472
|
+
var import_InclusionProof = require("@unicitylabs/state-transition-sdk/lib/api/InclusionProof.js");
|
|
3473
|
+
var import_InclusionProofResponse = require("@unicitylabs/state-transition-sdk/lib/api/InclusionProofResponse.js");
|
|
3474
|
+
var import_JsonRpcNetworkError = require("@unicitylabs/state-transition-sdk/lib/api/json-rpc/JsonRpcNetworkError.js");
|
|
3475
|
+
var import_RootTrustBase = require("@unicitylabs/state-transition-sdk/lib/api/bft/RootTrustBase.js");
|
|
3476
|
+
var import_InclusionProofUtils = require("@unicitylabs/state-transition-sdk/lib/util/InclusionProofUtils.js");
|
|
3477
|
+
var import_InclusionProofVerificationRule = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/rule/InclusionProofVerificationRule.js");
|
|
3478
|
+
var import_Token = require("@unicitylabs/state-transition-sdk/lib/transaction/Token.js");
|
|
3479
|
+
var import_MintTransaction = require("@unicitylabs/state-transition-sdk/lib/transaction/MintTransaction.js");
|
|
3480
|
+
var import_TransferTransaction = require("@unicitylabs/state-transition-sdk/lib/transaction/TransferTransaction.js");
|
|
3481
|
+
var import_CertifiedMintTransaction = require("@unicitylabs/state-transition-sdk/lib/transaction/CertifiedMintTransaction.js");
|
|
3482
|
+
var import_CertifiedTransferTransaction = require("@unicitylabs/state-transition-sdk/lib/transaction/CertifiedTransferTransaction.js");
|
|
3483
|
+
var import_TokenId = require("@unicitylabs/state-transition-sdk/lib/transaction/TokenId.js");
|
|
3484
|
+
var import_TokenType = require("@unicitylabs/state-transition-sdk/lib/transaction/TokenType.js");
|
|
3485
|
+
var import_TokenSalt = require("@unicitylabs/state-transition-sdk/lib/transaction/TokenSalt.js");
|
|
3486
|
+
var import_StateMask = require("@unicitylabs/state-transition-sdk/lib/transaction/StateMask.js");
|
|
3487
|
+
var import_MintJustificationVerifierService = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/MintJustificationVerifierService.js");
|
|
3488
|
+
var import_TokenIssuanceVerifierService = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/TokenIssuanceVerifierService.js");
|
|
3489
|
+
var import_VerificationContext = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/VerificationContext.js");
|
|
3490
|
+
var import_UnicityCertificateVerifier = require("@unicitylabs/state-transition-sdk/lib/api/bft/verification/UnicityCertificateVerifier.js");
|
|
3491
|
+
var import_UnicitySealQuorumSignaturesVerificationRule = require("@unicitylabs/state-transition-sdk/lib/api/bft/verification/rule/UnicitySealQuorumSignaturesVerificationRule.js");
|
|
3492
|
+
var import_VerifiedSealCache = require("@unicitylabs/state-transition-sdk/lib/api/bft/verification/VerifiedSealCache.js");
|
|
3493
|
+
var import_Secp256k1SignatureVerifier = require("@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/Secp256k1SignatureVerifier.js");
|
|
3494
|
+
var import_WorkerTokenVerifier = require("@unicitylabs/state-transition-sdk/lib/transaction/verification/worker/WorkerTokenVerifier.js");
|
|
3495
|
+
var import_EncodedPredicate = require("@unicitylabs/state-transition-sdk/lib/predicate/EncodedPredicate.js");
|
|
3496
|
+
var import_SignaturePredicate = require("@unicitylabs/state-transition-sdk/lib/predicate/builtin/SignaturePredicate.js");
|
|
3497
|
+
var import_SignaturePredicateUnlockScript = require("@unicitylabs/state-transition-sdk/lib/predicate/builtin/SignaturePredicateUnlockScript.js");
|
|
3498
|
+
var import_BurnPredicate = require("@unicitylabs/state-transition-sdk/lib/predicate/builtin/BurnPredicate.js");
|
|
3499
|
+
var import_PredicateVerifierService = require("@unicitylabs/state-transition-sdk/lib/predicate/verification/PredicateVerifierService.js");
|
|
3500
|
+
var import_SigningService = require("@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/SigningService.js");
|
|
3501
|
+
var import_Signature = require("@unicitylabs/state-transition-sdk/lib/crypto/secp256k1/Signature.js");
|
|
3502
|
+
var import_MintSigningService = require("@unicitylabs/state-transition-sdk/lib/crypto/MintSigningService.js");
|
|
3503
|
+
var import_HashAlgorithm = require("@unicitylabs/state-transition-sdk/lib/crypto/hash/HashAlgorithm.js");
|
|
3504
|
+
var import_DataHash = require("@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHash.js");
|
|
3505
|
+
var import_DataHasher = require("@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHasher.js");
|
|
3506
|
+
var import_DataHasherFactory = require("@unicitylabs/state-transition-sdk/lib/crypto/hash/DataHasherFactory.js");
|
|
3507
|
+
var import_CborSerializer = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborSerializer.js");
|
|
3508
|
+
var import_CborDeserializer = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborDeserializer.js");
|
|
3509
|
+
var import_CborError = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborError.js");
|
|
3510
|
+
var import_CborReader = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborReader.js");
|
|
3511
|
+
var import_MajorType = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/MajorType.js");
|
|
3512
|
+
var import_Asset = require("@unicitylabs/state-transition-sdk/lib/payment/asset/Asset.js");
|
|
3513
|
+
var import_AssetId = require("@unicitylabs/state-transition-sdk/lib/payment/asset/AssetId.js");
|
|
3514
|
+
var import_PaymentAssetCollection = require("@unicitylabs/state-transition-sdk/lib/payment/asset/PaymentAssetCollection.js");
|
|
3515
|
+
var import_TokenSplit = require("@unicitylabs/state-transition-sdk/lib/payment/TokenSplit.js");
|
|
3516
|
+
var import_SplitTokenRequest = require("@unicitylabs/state-transition-sdk/lib/payment/SplitTokenRequest.js");
|
|
3517
|
+
var import_SplitToken = require("@unicitylabs/state-transition-sdk/lib/payment/SplitToken.js");
|
|
3518
|
+
var import_SplitAllocationProof = require("@unicitylabs/state-transition-sdk/lib/payment/SplitAllocationProof.js");
|
|
3519
|
+
var import_SplitMintJustification = require("@unicitylabs/state-transition-sdk/lib/payment/SplitMintJustification.js");
|
|
3520
|
+
var import_SplitMintJustificationVerifier = require("@unicitylabs/state-transition-sdk/lib/payment/SplitMintJustificationVerifier.js");
|
|
3521
|
+
var import_VerificationStatus = require("@unicitylabs/state-transition-sdk/lib/verification/VerificationStatus.js");
|
|
3522
|
+
var import_VerificationResult = require("@unicitylabs/state-transition-sdk/lib/verification/VerificationResult.js");
|
|
3523
|
+
var import_HexConverter = require("@unicitylabs/state-transition-sdk/lib/util/HexConverter.js");
|
|
3524
|
+
var import_BigintConverter = require("@unicitylabs/state-transition-sdk/lib/util/BigintConverter.js");
|
|
3525
|
+
var import_BitString = require("@unicitylabs/state-transition-sdk/lib/util/BitString.js");
|
|
3526
|
+
|
|
3527
|
+
// token-engine/value-envelope.ts
|
|
3528
|
+
function isCoinlessEnvelope(envelope) {
|
|
3529
|
+
return envelope.startsWith("none_");
|
|
3530
|
+
}
|
|
3531
|
+
|
|
3500
3532
|
// modules/payments-v2/receive/Receive.ts
|
|
3501
3533
|
var ACK_BATCH_SIZE = 200;
|
|
3502
3534
|
var REFRESH_INTERVAL_MS = 2500;
|
|
@@ -3641,7 +3673,7 @@ async function screen(deps, engine, entry) {
|
|
|
3641
3673
|
tokenId: keys.tokenId,
|
|
3642
3674
|
stateHash: keys.stateHash,
|
|
3643
3675
|
assets: toAssetAmounts(token),
|
|
3644
|
-
...
|
|
3676
|
+
...isCoinlessEnvelope(token.valueEnvelope) ? { tokenType: token.tokenType } : {}
|
|
3645
3677
|
}
|
|
3646
3678
|
};
|
|
3647
3679
|
}
|
|
@@ -3778,9 +3810,6 @@ function claimAck(entry) {
|
|
|
3778
3810
|
function rejectAck(entry, reason) {
|
|
3779
3811
|
return { deliveryId: entry.deliveryId, disposition: "rejected", reason, cursor: entry.cursor };
|
|
3780
3812
|
}
|
|
3781
|
-
function isCoinlessEnvelope2(envelope) {
|
|
3782
|
-
return envelope.startsWith("none_");
|
|
3783
|
-
}
|
|
3784
3813
|
function toAssetAmounts(token) {
|
|
3785
3814
|
return (token.value?.assets ?? []).map((asset) => ({
|
|
3786
3815
|
coinId: asset.coinId,
|
|
@@ -4355,7 +4384,7 @@ var SpendQueue = class {
|
|
|
4355
4384
|
* can release, so queueing would block until a timeout on a spend that cannot
|
|
4356
4385
|
* become possible.
|
|
4357
4386
|
*/
|
|
4358
|
-
|
|
4387
|
+
planWhole(reservationId, tokenId) {
|
|
4359
4388
|
if (this.destroyed) {
|
|
4360
4389
|
throw new SphereError("Module has been destroyed", "MODULE_DESTROYED");
|
|
4361
4390
|
}
|
|
@@ -4363,11 +4392,8 @@ var SpendQueue = class {
|
|
|
4363
4392
|
if (unproven !== null) {
|
|
4364
4393
|
throw new SphereError(`Cannot spend yet: ${unproven}`, "SEND_SYNC_PENDING");
|
|
4365
4394
|
}
|
|
4366
|
-
if (this.deps.
|
|
4367
|
-
throw new SphereError(
|
|
4368
|
-
`Token ${tokenId} is not a spendable coinless holding`,
|
|
4369
|
-
"VALIDATION_ERROR"
|
|
4370
|
-
);
|
|
4395
|
+
if (this.deps.spendableToken?.(tokenId) !== true) {
|
|
4396
|
+
throw new SphereError(`Token ${tokenId} is not a spendable holding`, "VALIDATION_ERROR");
|
|
4371
4397
|
}
|
|
4372
4398
|
const holder = this.deps.ledger.holderOf(tokenId);
|
|
4373
4399
|
if (holder !== void 0) {
|
|
@@ -4568,7 +4594,7 @@ function composeFacadeParts(deps, hooks) {
|
|
|
4568
4594
|
const queue = new SpendQueue({
|
|
4569
4595
|
ledger,
|
|
4570
4596
|
getPool: (coinId) => view.pool(coinId),
|
|
4571
|
-
|
|
4597
|
+
spendableToken: (tokenId) => view.spendableToken(tokenId),
|
|
4572
4598
|
...deps.workBudget !== void 0 ? { workBudget: deps.workBudget } : {}
|
|
4573
4599
|
});
|
|
4574
4600
|
const historyStore = new History({
|
|
@@ -4649,12 +4675,12 @@ function buildMachineDeps(deps, hooks, historyStore) {
|
|
|
4649
4675
|
...deps.ownNametag !== void 0 ? { ownNametag: deps.ownNametag } : {},
|
|
4650
4676
|
emit: deps.emit,
|
|
4651
4677
|
now: deps.now ?? Date.now,
|
|
4652
|
-
recordHistory: async ({ transferId, payload, committedAmount }) => {
|
|
4678
|
+
recordHistory: async ({ transferId, payload, committedAmount, committedAssets }) => {
|
|
4653
4679
|
await historyStore.recordSent({
|
|
4654
4680
|
transferId,
|
|
4655
4681
|
// §5.9: the SETTLED amount, never payload.amount — the plan. A token
|
|
4656
4682
|
// spend moved no coin: `assets: []` + tokenId (wallet-api#151 / §10).
|
|
4657
|
-
...payload
|
|
4683
|
+
...isWholeIntent(payload) ? { assets: committedAssets ?? [], tokenId: payload.direct[0] } : { assets: [{ coinId: payload.coinId, amount: committedAmount }] },
|
|
4658
4684
|
recipientPubkey: payload.recipient,
|
|
4659
4685
|
...payload.memo !== void 0 ? { memo: payload.memo } : {}
|
|
4660
4686
|
});
|
|
@@ -4869,10 +4895,14 @@ var PaymentsFacade = class {
|
|
|
4869
4895
|
return { queue: this.queue, view: this.view, storagePort: this.deps.storagePort, cache: this.prewarmed };
|
|
4870
4896
|
}
|
|
4871
4897
|
send(request) {
|
|
4872
|
-
return this.track(this.
|
|
4898
|
+
return this.track(this.runJob({ kind: "coin", request }, request.amount));
|
|
4899
|
+
}
|
|
4900
|
+
sendWholeToken(request) {
|
|
4901
|
+
return this.track(this.runJob({ kind: "whole", request, requireCoinless: false }, "0"));
|
|
4873
4902
|
}
|
|
4903
|
+
/** NFT-scoped twin: refuses a valued source. */
|
|
4874
4904
|
sendCoinless(request) {
|
|
4875
|
-
return this.track(this.
|
|
4905
|
+
return this.track(this.runJob({ kind: "whole", request, requireCoinless: true }, "0"));
|
|
4876
4906
|
}
|
|
4877
4907
|
async receive() {
|
|
4878
4908
|
const transfers = await this.track(this.receiveLoop.drainOnce());
|
|
@@ -4920,13 +4950,6 @@ var PaymentsFacade = class {
|
|
|
4920
4950
|
// ── send policy (§5.5 + old-loop parity; the machine stays policy-free) ────
|
|
4921
4951
|
/** The ONE place a send() outcome is shaped: success emits in finishSend, a
|
|
4922
4952
|
* CLEAN rejection emits `transfer:updated{status:'failed'}` here (§4). */
|
|
4923
|
-
sendOutcome(request) {
|
|
4924
|
-
return this.runJob({ kind: "coin", request }, request.amount);
|
|
4925
|
-
}
|
|
4926
|
-
/** A token spend has no amount; '0' keeps the shortfall arithmetic total-free. */
|
|
4927
|
-
sendCoinlessOutcome(request) {
|
|
4928
|
-
return this.runJob({ kind: "coinless", request }, "0");
|
|
4929
|
-
}
|
|
4930
4953
|
async runJob(job, amount) {
|
|
4931
4954
|
const run = {
|
|
4932
4955
|
amount,
|
|
@@ -4971,7 +4994,7 @@ var PaymentsFacade = class {
|
|
|
4971
4994
|
const disposition = await this.runAttempt(ctx);
|
|
4972
4995
|
if (disposition.kind === "rethrow") throw partialize(disposition.error, run);
|
|
4973
4996
|
if (disposition.kind === "retry-full") {
|
|
4974
|
-
if (job.kind === "
|
|
4997
|
+
if (job.kind === "whole" || attempt >= MAX_RESELECT) throw partialize(disposition.error, run);
|
|
4975
4998
|
continue;
|
|
4976
4999
|
}
|
|
4977
5000
|
if (disposition.kind === "success") {
|
|
@@ -5075,13 +5098,19 @@ var PaymentsFacade = class {
|
|
|
5075
5098
|
async planAndMaterialize(recipientPubkey, job, run) {
|
|
5076
5099
|
const transferId = this.newId();
|
|
5077
5100
|
run.lastTransferId = transferId;
|
|
5078
|
-
if (job.kind === "
|
|
5079
|
-
const spend2 = this.queue.
|
|
5101
|
+
if (job.kind === "whole") {
|
|
5102
|
+
const spend2 = this.queue.planWhole(transferId, job.request.tokenId);
|
|
5080
5103
|
const sourceIds2 = this.markPlanned(transferId, "", spend2);
|
|
5081
5104
|
try {
|
|
5082
|
-
return await
|
|
5083
|
-
{ engine: this.engine(), storagePort: this.deps.storagePort },
|
|
5084
|
-
{
|
|
5105
|
+
return await materializeWholeSpend(
|
|
5106
|
+
{ engine: this.engine(), storagePort: this.deps.storagePort, registry: this.deps.registry, now: this.nowMs() },
|
|
5107
|
+
{
|
|
5108
|
+
transferId,
|
|
5109
|
+
recipientPubkey,
|
|
5110
|
+
request: job.request,
|
|
5111
|
+
sourceIds: sourceIds2,
|
|
5112
|
+
requireCoinless: job.requireCoinless
|
|
5113
|
+
}
|
|
5085
5114
|
);
|
|
5086
5115
|
} catch (err) {
|
|
5087
5116
|
this.settleFailure(transferId, "", sourceIds2);
|