@unicitylabs/sphere-sdk 0.16.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 +11 -5
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.d.cts +4 -1
- package/dist/connect/index.d.ts +4 -1
- package/dist/connect/index.js +11 -5
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +692 -268
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +69 -0
- package/dist/core/index.d.ts +69 -0
- package/dist/core/index.js +692 -268
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +11 -5
- package/dist/impl/browser/connect/index.cjs.map +1 -1
- package/dist/impl/browser/connect/index.d.cts +3 -1
- package/dist/impl/browser/connect/index.d.ts +3 -1
- package/dist/impl/browser/connect/index.js +11 -5
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/nodejs/connect/index.cjs +10 -4
- package/dist/impl/nodejs/connect/index.cjs.map +1 -1
- package/dist/impl/nodejs/connect/index.d.cts +1 -1
- package/dist/impl/nodejs/connect/index.d.ts +1 -1
- package/dist/impl/nodejs/connect/index.js +10 -4
- package/dist/impl/nodejs/connect/index.js.map +1 -1
- package/dist/impl/nodejs/index.d.cts +11 -0
- package/dist/impl/nodejs/index.d.ts +11 -0
- package/dist/impl/shared/wallet-api/index.d.cts +11 -0
- package/dist/impl/shared/wallet-api/index.d.ts +11 -0
- package/dist/impl/wallet-api-v2/index.cjs +2 -0
- package/dist/impl/wallet-api-v2/index.cjs.map +1 -1
- package/dist/impl/wallet-api-v2/index.d.cts +13 -0
- package/dist/impl/wallet-api-v2/index.d.ts +13 -0
- package/dist/impl/wallet-api-v2/index.js +2 -0
- package/dist/impl/wallet-api-v2/index.js.map +1 -1
- package/dist/index.cjs +692 -268
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +63 -1
- package/dist/index.d.ts +63 -1
- package/dist/index.js +692 -268
- package/dist/index.js.map +1 -1
- package/dist/modules/payments-v2/index.cjs +767 -398
- package/dist/modules/payments-v2/index.cjs.map +1 -1
- package/dist/modules/payments-v2/index.d.cts +91 -14
- package/dist/modules/payments-v2/index.d.ts +91 -14
- package/dist/modules/payments-v2/index.js +767 -398
- package/dist/modules/payments-v2/index.js.map +1 -1
- package/dist/token-engine/index.cjs +132 -34
- package/dist/token-engine/index.cjs.map +1 -1
- package/dist/token-engine/index.d.cts +19 -0
- package/dist/token-engine/index.d.ts +19 -0
- package/dist/token-engine/index.js +132 -34
- package/dist/token-engine/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -78,6 +78,8 @@ var import_DataHasherFactory = require("@unicitylabs/state-transition-sdk/lib/cr
|
|
|
78
78
|
var import_CborSerializer = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborSerializer.js");
|
|
79
79
|
var import_CborDeserializer = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborDeserializer.js");
|
|
80
80
|
var import_CborError = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborError.js");
|
|
81
|
+
var import_CborReader = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/CborReader.js");
|
|
82
|
+
var import_MajorType = require("@unicitylabs/state-transition-sdk/lib/serialization/cbor/MajorType.js");
|
|
81
83
|
var import_Asset = require("@unicitylabs/state-transition-sdk/lib/payment/asset/Asset.js");
|
|
82
84
|
var import_AssetId = require("@unicitylabs/state-transition-sdk/lib/payment/asset/AssetId.js");
|
|
83
85
|
var import_PaymentAssetCollection = require("@unicitylabs/state-transition-sdk/lib/payment/asset/PaymentAssetCollection.js");
|
|
@@ -1035,6 +1037,123 @@ async function burntTokenFromCheckpoint(deps, storedBytes, reDerivedBurnTx, sour
|
|
|
1035
1037
|
return burntToken;
|
|
1036
1038
|
}
|
|
1037
1039
|
|
|
1040
|
+
// token-engine/value-envelope.ts
|
|
1041
|
+
var SELF_DESCRIBED_CBOR_TAG = 55799n;
|
|
1042
|
+
var CBOR_MAJOR_TYPE_MASK = 224;
|
|
1043
|
+
var describe = (error) => error instanceof Error ? error.message : String(error);
|
|
1044
|
+
var invalid = (message) => new SphereError(message, "VALIDATION_ERROR");
|
|
1045
|
+
function majorTypeOf(bytes) {
|
|
1046
|
+
const first = bytes.at(0);
|
|
1047
|
+
return first === void 0 ? null : first & CBOR_MAJOR_TYPE_MASK;
|
|
1048
|
+
}
|
|
1049
|
+
function headTagNumber(bytes) {
|
|
1050
|
+
try {
|
|
1051
|
+
return new import_CborReader.CborReader(bytes).readLength(import_MajorType.MajorType.TAG);
|
|
1052
|
+
} catch {
|
|
1053
|
+
return null;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
function isAssetShaped(item) {
|
|
1057
|
+
try {
|
|
1058
|
+
return import_CborDeserializer.CborDeserializer.decodeArray(item, 2).every(
|
|
1059
|
+
(field) => majorTypeOf(field) === import_MajorType.MajorType.BYTE_STRING
|
|
1060
|
+
);
|
|
1061
|
+
} catch {
|
|
1062
|
+
return false;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
function arrayItemsOrNull(bytes) {
|
|
1066
|
+
try {
|
|
1067
|
+
return import_CborDeserializer.CborDeserializer.decodeArray(bytes);
|
|
1068
|
+
} catch {
|
|
1069
|
+
return null;
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
function decodeSphere(genesisData) {
|
|
1073
|
+
try {
|
|
1074
|
+
return SpherePaymentData.fromCBOR(genesisData).toValue();
|
|
1075
|
+
} catch (error) {
|
|
1076
|
+
throw invalid(`Failed to decode token payment data: ${describe(error)}`);
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
function taggedItemBody(genesisData) {
|
|
1080
|
+
try {
|
|
1081
|
+
return import_CborDeserializer.CborDeserializer.decodeTag(genesisData).data;
|
|
1082
|
+
} catch (error) {
|
|
1083
|
+
throw invalid(
|
|
1084
|
+
`Token value payload is a CBOR tag whose item is malformed or carries trailing bytes: ${describe(error)}`
|
|
1085
|
+
);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
function selfDescribedBodyCarriesValue(body) {
|
|
1089
|
+
const major = majorTypeOf(body);
|
|
1090
|
+
if (major === import_MajorType.MajorType.TAG) {
|
|
1091
|
+
const inner = headTagNumber(body);
|
|
1092
|
+
return inner === SpherePaymentData.CBOR_TAG || inner === SELF_DESCRIBED_CBOR_TAG;
|
|
1093
|
+
}
|
|
1094
|
+
if (major === import_MajorType.MajorType.ARRAY) {
|
|
1095
|
+
const items = arrayItemsOrNull(body);
|
|
1096
|
+
return items !== null && items.some(isAssetShaped);
|
|
1097
|
+
}
|
|
1098
|
+
return false;
|
|
1099
|
+
}
|
|
1100
|
+
function classifyTagged(genesisData) {
|
|
1101
|
+
const tag = headTagNumber(genesisData);
|
|
1102
|
+
if (tag === null) {
|
|
1103
|
+
throw invalid(
|
|
1104
|
+
"Token value payload has an unreadable or non-canonically encoded CBOR tag head \u2014 it could be a malformed SpherePaymentData envelope"
|
|
1105
|
+
);
|
|
1106
|
+
}
|
|
1107
|
+
if (tag === SpherePaymentData.CBOR_TAG) {
|
|
1108
|
+
return { envelope: "sphere", value: decodeSphere(genesisData) };
|
|
1109
|
+
}
|
|
1110
|
+
const body = taggedItemBody(genesisData);
|
|
1111
|
+
if (tag === SELF_DESCRIBED_CBOR_TAG && selfDescribedBodyCarriesValue(body)) {
|
|
1112
|
+
throw invalid(
|
|
1113
|
+
"Token value payload is a value envelope wrapped in the self-described CBOR tag 55799 (RFC 8949 \xA73.4.6), which no codec here unwraps \u2014 its coins would be invisible. Emit the envelope without the self-describe prefix"
|
|
1114
|
+
);
|
|
1115
|
+
}
|
|
1116
|
+
return { envelope: "none_tag", value: null };
|
|
1117
|
+
}
|
|
1118
|
+
function classifyArray(genesisData) {
|
|
1119
|
+
const items = arrayItemsOrNull(genesisData);
|
|
1120
|
+
if (items === null) {
|
|
1121
|
+
throw invalid("Token value payload is not PaymentAssetCollection: malformed CBOR array");
|
|
1122
|
+
}
|
|
1123
|
+
return items.some(isAssetShaped) ? { envelope: "bare_collection", value: null } : { envelope: "none_other", value: null };
|
|
1124
|
+
}
|
|
1125
|
+
function classifyValueEnvelope(genesisData) {
|
|
1126
|
+
if (genesisData === null) return { envelope: "none_absent", value: null };
|
|
1127
|
+
const major = majorTypeOf(genesisData);
|
|
1128
|
+
if (major === null) return { envelope: "none_absent", value: null };
|
|
1129
|
+
if (major === import_MajorType.MajorType.TAG) return classifyTagged(genesisData);
|
|
1130
|
+
if (major === import_MajorType.MajorType.ARRAY) return classifyArray(genesisData);
|
|
1131
|
+
return { envelope: "none_other", value: null };
|
|
1132
|
+
}
|
|
1133
|
+
function wrapToken(sdkToken) {
|
|
1134
|
+
const { envelope, value } = classifyValueEnvelope(sdkToken.genesis.data);
|
|
1135
|
+
const blob = {
|
|
1136
|
+
tokenId: import_HexConverter.HexConverter.encode(sdkToken.id.bytes),
|
|
1137
|
+
token: sdkToken.toCBOR()
|
|
1138
|
+
};
|
|
1139
|
+
return {
|
|
1140
|
+
sdkToken,
|
|
1141
|
+
blob,
|
|
1142
|
+
value,
|
|
1143
|
+
valueEnvelope: envelope,
|
|
1144
|
+
tokenType: import_HexConverter.HexConverter.encode(sdkToken.type.bytes)
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
function assertMintableData(data) {
|
|
1148
|
+
try {
|
|
1149
|
+
classifyValueEnvelope(data);
|
|
1150
|
+
} catch (error) {
|
|
1151
|
+
throw invalid(
|
|
1152
|
+
`Cannot mint a data token with this payload: ${describe(error)}. Raw bytes starting in the CBOR array (0x80-0x9f) or tag (0xc0-0xdf) range must be well-formed canonical CBOR; wrap them in a CBOR byte string, map, text string, or a tag other than 39050/55799.`
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1038
1157
|
// token-engine/SphereTokenEngine.ts
|
|
1039
1158
|
var DEFAULT_PROOF_POLL_INTERVAL_MS = 300;
|
|
1040
1159
|
var MAX_MINT_CONCURRENCY = 8;
|
|
@@ -1091,7 +1210,7 @@ var SphereTokenEngine = class {
|
|
|
1091
1210
|
return sdkToken.latestTransaction.data;
|
|
1092
1211
|
}
|
|
1093
1212
|
const data = sdkToken.genesis.data;
|
|
1094
|
-
if (data &&
|
|
1213
|
+
if (data && classifyValueEnvelope(data).envelope === "sphere") {
|
|
1095
1214
|
return SpherePaymentData.fromCBOR(data).memo;
|
|
1096
1215
|
}
|
|
1097
1216
|
return null;
|
|
@@ -1121,9 +1240,10 @@ var SphereTokenEngine = class {
|
|
|
1121
1240
|
);
|
|
1122
1241
|
const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);
|
|
1123
1242
|
const token = await import_Token.Token.mint(certified, this.deps.verificationContext);
|
|
1124
|
-
return
|
|
1243
|
+
return wrapToken(token);
|
|
1125
1244
|
}
|
|
1126
1245
|
async mintDataToken(params, options) {
|
|
1246
|
+
assertMintableData(params.data);
|
|
1127
1247
|
const recipient = import_SignaturePredicate.SignaturePredicate.create(params.recipientPubkey);
|
|
1128
1248
|
const tokenType = params.tokenType ? new import_TokenType.TokenType(params.tokenType) : import_TokenType.TokenType.generate();
|
|
1129
1249
|
const salt = params.salt ? import_TokenSalt.TokenSalt.fromBytes(params.salt) : import_TokenSalt.TokenSalt.generate();
|
|
@@ -1138,7 +1258,7 @@ var SphereTokenEngine = class {
|
|
|
1138
1258
|
);
|
|
1139
1259
|
const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);
|
|
1140
1260
|
const token = await import_Token.Token.mint(certified, this.deps.verificationContext);
|
|
1141
|
-
return
|
|
1261
|
+
return wrapToken(token);
|
|
1142
1262
|
}
|
|
1143
1263
|
async transfer(params, options) {
|
|
1144
1264
|
this.assertOwned(params.token);
|
|
@@ -1161,13 +1281,19 @@ var SphereTokenEngine = class {
|
|
|
1161
1281
|
);
|
|
1162
1282
|
const certified = await transferTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);
|
|
1163
1283
|
const transferred = await params.token.sdkToken.transfer(certified, this.deps.verificationContext);
|
|
1164
|
-
return
|
|
1284
|
+
return wrapToken(transferred);
|
|
1165
1285
|
}
|
|
1166
1286
|
async split(params, options) {
|
|
1167
1287
|
this.assertOwned(params.token);
|
|
1168
1288
|
if (params.outputs.length === 0) {
|
|
1169
1289
|
throw new SphereError("Split requires at least one output", "VALIDATION_ERROR");
|
|
1170
1290
|
}
|
|
1291
|
+
if (params.token.value === null) {
|
|
1292
|
+
throw new SphereError(
|
|
1293
|
+
`Cannot split token ${params.token.blob.tokenId}: its genesis payload carries no value this SDK can read (envelope: ${params.token.valueEnvelope}). A coinless token can only be transferred whole.`,
|
|
1294
|
+
"VALIDATION_ERROR"
|
|
1295
|
+
);
|
|
1296
|
+
}
|
|
1171
1297
|
const transferId = this.resolveTransferId(options);
|
|
1172
1298
|
const requests = params.outputs.map(
|
|
1173
1299
|
(o, i) => import_SplitTokenRequest.SplitTokenRequest.create(
|
|
@@ -1289,7 +1415,7 @@ var SphereTokenEngine = class {
|
|
|
1289
1415
|
const proof = await this.submitSplitMintLeg(certData, mintTx, options);
|
|
1290
1416
|
const certified = await mintTx.toCertifiedTransaction(this.deps.trustBase, this.deps.predicateVerifier, this.deps.unicityCertificateVerifier, proof);
|
|
1291
1417
|
const token = await import_Token.Token.mint(certified, this.deps.verificationContext);
|
|
1292
|
-
return
|
|
1418
|
+
return wrapToken(token);
|
|
1293
1419
|
}
|
|
1294
1420
|
/**
|
|
1295
1421
|
* Submit one split-mint leg. A `TRANSACTION_HASH_MISMATCH` on a mint leg is NOT a foreign spend
|
|
@@ -1347,7 +1473,7 @@ var SphereTokenEngine = class {
|
|
|
1347
1473
|
"VALIDATION_ERROR"
|
|
1348
1474
|
);
|
|
1349
1475
|
}
|
|
1350
|
-
return
|
|
1476
|
+
return wrapToken(sdkToken);
|
|
1351
1477
|
}
|
|
1352
1478
|
// ── internals ────────────────────────────────────────────────────────────────
|
|
1353
1479
|
/**
|
|
@@ -1459,34 +1585,6 @@ var SphereTokenEngine = class {
|
|
|
1459
1585
|
throw new SphereError("Cannot transfer a token not owned by this engine identity", "VALIDATION_ERROR");
|
|
1460
1586
|
}
|
|
1461
1587
|
}
|
|
1462
|
-
/** Wrap an SDK token into a SphereToken: cache its blob (incl. stable tokenId) + decoded value. */
|
|
1463
|
-
wrapToken(sdkToken) {
|
|
1464
|
-
const data = sdkToken.genesis.data;
|
|
1465
|
-
let value = null;
|
|
1466
|
-
if (data && this.isSpherePaymentData(data)) {
|
|
1467
|
-
try {
|
|
1468
|
-
value = SpherePaymentData.fromCBOR(data).toValue();
|
|
1469
|
-
} catch (err) {
|
|
1470
|
-
throw new SphereError(
|
|
1471
|
-
`Failed to decode token payment data: ${err instanceof Error ? err.message : String(err)}`,
|
|
1472
|
-
"VALIDATION_ERROR"
|
|
1473
|
-
);
|
|
1474
|
-
}
|
|
1475
|
-
}
|
|
1476
|
-
const blob = {
|
|
1477
|
-
tokenId: import_HexConverter.HexConverter.encode(sdkToken.id.bytes),
|
|
1478
|
-
token: sdkToken.toCBOR()
|
|
1479
|
-
};
|
|
1480
|
-
return { sdkToken, blob, value };
|
|
1481
|
-
}
|
|
1482
|
-
/** True if the bytes are a SpherePaymentData envelope (value token) vs a raw data token. */
|
|
1483
|
-
isSpherePaymentData(data) {
|
|
1484
|
-
try {
|
|
1485
|
-
return import_CborDeserializer.CborDeserializer.decodeTag(data).tag === SpherePaymentData.CBOR_TAG;
|
|
1486
|
-
} catch {
|
|
1487
|
-
return false;
|
|
1488
|
-
}
|
|
1489
|
-
}
|
|
1490
1588
|
/**
|
|
1491
1589
|
* Terminate the verification worker pool, if this engine was configured with
|
|
1492
1590
|
* one. Idempotent — the pool's dispose only touches workers it spawned.
|