@unicitylabs/sphere-sdk 0.17.2-dev.1 → 0.17.2-dev.3
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 +202 -8
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.d.cts +81 -4
- package/dist/connect/index.d.ts +81 -4
- package/dist/connect/index.js +202 -8
- package/dist/connect/index.js.map +1 -1
- package/dist/core/index.cjs +48 -21
- 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 +48 -21
- package/dist/core/index.js.map +1 -1
- package/dist/impl/browser/connect/index.cjs +17 -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 +17 -5
- package/dist/impl/browser/connect/index.js.map +1 -1
- package/dist/impl/nodejs/connect/index.cjs +16 -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 +16 -4
- package/dist/impl/nodejs/connect/index.js.map +1 -1
- package/dist/impl/wallet-api-v2/index.cjs +3 -0
- package/dist/impl/wallet-api-v2/index.cjs.map +1 -1
- package/dist/impl/wallet-api-v2/index.js +3 -0
- package/dist/impl/wallet-api-v2/index.js.map +1 -1
- package/dist/index.cjs +67 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.js +64 -21
- package/dist/index.js.map +1 -1
- package/dist/modules/payments-v2/index.cjs +40 -6
- package/dist/modules/payments-v2/index.cjs.map +1 -1
- package/dist/modules/payments-v2/index.d.cts +22 -1
- package/dist/modules/payments-v2/index.d.ts +22 -1
- package/dist/modules/payments-v2/index.js +37 -6
- package/dist/modules/payments-v2/index.js.map +1 -1
- package/dist/token-engine/index.cjs +67 -21
- package/dist/token-engine/index.cjs.map +1 -1
- package/dist/token-engine/index.d.cts +28 -4
- package/dist/token-engine/index.d.ts +28 -4
- package/dist/token-engine/index.js +64 -21
- package/dist/token-engine/index.js.map +1 -1
- package/package.json +1 -1
package/dist/core/index.cjs
CHANGED
|
@@ -9869,7 +9869,8 @@ var NFT_MEDIA_TAG = 39053n;
|
|
|
9869
9869
|
var NFT_LINK_TAG = 39054n;
|
|
9870
9870
|
var NFT_SIGNED_TAG = 39055n;
|
|
9871
9871
|
var NFT_FORMAT_VERSION = 1n;
|
|
9872
|
-
var
|
|
9872
|
+
var NFT_DOCUMENT_MEDIA_TYPE = "application/vnd.unicity.nft+cbor";
|
|
9873
|
+
var METADATA_ARITY = 9;
|
|
9873
9874
|
var MEDIA_ARITY = 3;
|
|
9874
9875
|
var LINK_ARITY = 4;
|
|
9875
9876
|
var SIGNED_ARITY = 4;
|
|
@@ -9877,12 +9878,15 @@ var CREATOR_BYTES = 33;
|
|
|
9877
9878
|
var SIGNATURE_BYTES = 65;
|
|
9878
9879
|
var MAX_URI_LENGTH = 2048;
|
|
9879
9880
|
var LINK_SCHEMES = ["https://", "ipfs://", "ar://"];
|
|
9880
|
-
var SIGNED_DOMAIN = "
|
|
9881
|
+
var SIGNED_DOMAIN = new TextEncoder().encode("UNICITY_NFT_SIGNED");
|
|
9881
9882
|
var MEDIA_TYPE_PATTERN = /^[a-z0-9][a-z0-9!#$&^_.+-]{0,126}\/[a-z0-9][a-z0-9!#$&^_.+-]{0,126}$/;
|
|
9882
9883
|
var SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/i;
|
|
9884
|
+
var COLLECTION_ID_PATTERN = /^(?:[0-9a-f]{2}){1,64}$/i;
|
|
9883
9885
|
var LONE_SURROGATE = /\p{Cs}/u;
|
|
9884
9886
|
var CBOR_MAJOR_TYPE_MASK = 224;
|
|
9885
9887
|
var ATTRIBUTE_VALUE_RULE = "must be non-empty text or an integer within \xB1(2^53 \u2212 1) \u2014 write decimals and larger numbers as text";
|
|
9888
|
+
var COLLECTION_ID_RULE = "must be null or 1\u201364 bytes as even-length hex (2\u2013128 characters)";
|
|
9889
|
+
var DOCUMENT_AS_MEDIA_RULE = `must not be ${NFT_DOCUMENT_MEDIA_TYPE}: a document link is a token's content, never media`;
|
|
9886
9890
|
var UTF8 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
9887
9891
|
function refuse(field, rule, cause) {
|
|
9888
9892
|
return new SphereError(`Invalid NFT ${field}: ${rule}`, "VALIDATION_ERROR", cause);
|
|
@@ -9894,6 +9898,7 @@ var fieldName = (prefix, name) => prefix === "" ? name : `${prefix}.${name}`;
|
|
|
9894
9898
|
var isText = (value) => typeof value === "string" && value.length > 0 && !LONE_SURROGATE.test(value);
|
|
9895
9899
|
var isBytes3 = (value, length) => value instanceof Uint8Array && (length === void 0 ? value.length > 0 : value.length === length);
|
|
9896
9900
|
var isMediaType = (value) => typeof value === "string" && MEDIA_TYPE_PATTERN.test(value);
|
|
9901
|
+
var isCollectionId = (value) => typeof value === "string" && COLLECTION_ID_PATTERN.test(value);
|
|
9897
9902
|
var isAttributeValue = (value) => typeof value === "number" ? Number.isSafeInteger(value) : isText(value);
|
|
9898
9903
|
function hasSpaceOrControl(value) {
|
|
9899
9904
|
for (let i = 0; i < value.length; i++) {
|
|
@@ -9936,8 +9941,9 @@ function checkLink(prefix, link) {
|
|
|
9936
9941
|
function checkMediaRef(field, ref) {
|
|
9937
9942
|
if (ref === null) return;
|
|
9938
9943
|
if (ref?.kind === "media") return checkMedia(field, ref);
|
|
9939
|
-
if (ref?.kind
|
|
9940
|
-
|
|
9944
|
+
if (ref?.kind !== "link") throw refuse(field, "must be an NftMedia, an NftLink or null");
|
|
9945
|
+
checkLink(field, ref);
|
|
9946
|
+
ensure(!isNftDocumentLink(ref), fieldName(field, "media_type"), DOCUMENT_AS_MEDIA_RULE);
|
|
9941
9947
|
}
|
|
9942
9948
|
function checkAttributes(attributes) {
|
|
9943
9949
|
ensure(Array.isArray(attributes), "attributes", "must be an array \u2014 [] when there are none");
|
|
@@ -9954,6 +9960,7 @@ function checkMetadata(metadata) {
|
|
|
9954
9960
|
checkOptionalText("external_url", metadata.external_url);
|
|
9955
9961
|
checkAttributes(metadata.attributes);
|
|
9956
9962
|
checkOptionalText("collection", metadata.collection);
|
|
9963
|
+
ensure(metadata.collection_id === null || isCollectionId(metadata.collection_id), "collection_id", COLLECTION_ID_RULE);
|
|
9957
9964
|
}
|
|
9958
9965
|
function checkContent(content) {
|
|
9959
9966
|
switch (content?.kind) {
|
|
@@ -10011,6 +10018,7 @@ function arrayCbor(items) {
|
|
|
10011
10018
|
}
|
|
10012
10019
|
return out;
|
|
10013
10020
|
}
|
|
10021
|
+
var optionalHexBytes = (value) => import_CborSerializer.CborSerializer.encodeNullable(value, (hex) => import_CborSerializer.CborSerializer.encodeByteString(import_HexConverter.HexConverter.decode(hex.toLowerCase())));
|
|
10014
10022
|
function metadataCbor(metadata) {
|
|
10015
10023
|
return versioned(
|
|
10016
10024
|
NFT_METADATA_TAG,
|
|
@@ -10020,7 +10028,8 @@ function metadataCbor(metadata) {
|
|
|
10020
10028
|
mediaRefCbor(metadata.animation_url),
|
|
10021
10029
|
optionalText(metadata.external_url),
|
|
10022
10030
|
arrayCbor(metadata.attributes.map(attributeCbor)),
|
|
10023
|
-
optionalText(metadata.collection)
|
|
10031
|
+
optionalText(metadata.collection),
|
|
10032
|
+
optionalHexBytes(metadata.collection_id)
|
|
10024
10033
|
);
|
|
10025
10034
|
}
|
|
10026
10035
|
function encodeNftContent(content) {
|
|
@@ -10078,13 +10087,14 @@ function decodeMedia(body) {
|
|
|
10078
10087
|
const [, mediaType, bytes] = versionedFields(body, MEDIA_ARITY);
|
|
10079
10088
|
return { kind: "media", media_type: decodeText(mediaType), bytes: import_CborDeserializer.CborDeserializer.decodeByteString(bytes) };
|
|
10080
10089
|
}
|
|
10090
|
+
var decodeHex = (item) => import_HexConverter.HexConverter.encode(import_CborDeserializer.CborDeserializer.decodeByteString(item));
|
|
10081
10091
|
function decodeLink(body) {
|
|
10082
10092
|
const [, mediaType, uri, digest] = versionedFields(body, LINK_ARITY);
|
|
10083
10093
|
return {
|
|
10084
10094
|
kind: "link",
|
|
10085
10095
|
media_type: decodeText(mediaType),
|
|
10086
10096
|
uri: decodeText(uri),
|
|
10087
|
-
sha256:
|
|
10097
|
+
sha256: decodeHex(digest)
|
|
10088
10098
|
};
|
|
10089
10099
|
}
|
|
10090
10100
|
function decodeMetadata(body) {
|
|
@@ -10097,7 +10107,8 @@ function decodeMetadata(body) {
|
|
|
10097
10107
|
animation_url: decodeMediaRef("animation_url", fields[4]),
|
|
10098
10108
|
external_url: decodeOptionalText(fields[5]),
|
|
10099
10109
|
attributes: decodeAttributes(fields[6]),
|
|
10100
|
-
collection: decodeOptionalText(fields[7])
|
|
10110
|
+
collection: decodeOptionalText(fields[7]),
|
|
10111
|
+
collection_id: import_CborDeserializer.CborDeserializer.decodeNullable(fields[8], decodeHex)
|
|
10101
10112
|
};
|
|
10102
10113
|
}
|
|
10103
10114
|
var MEDIA_REF_DECODERS = /* @__PURE__ */ new Map([
|
|
@@ -10143,20 +10154,26 @@ function parseNftPayload(data) {
|
|
|
10143
10154
|
return null;
|
|
10144
10155
|
}
|
|
10145
10156
|
}
|
|
10146
|
-
function
|
|
10157
|
+
function isNftDocumentLink(content) {
|
|
10158
|
+
return content?.kind === "link" && content.media_type === NFT_DOCUMENT_MEDIA_TYPE;
|
|
10159
|
+
}
|
|
10160
|
+
function nftSignedDigest(context, payload) {
|
|
10147
10161
|
const preimage = import_CborSerializer.CborSerializer.encodeArray(
|
|
10148
|
-
import_CborSerializer.CborSerializer.
|
|
10149
|
-
|
|
10150
|
-
|
|
10162
|
+
import_CborSerializer.CborSerializer.encodeByteString(SIGNED_DOMAIN),
|
|
10163
|
+
import_CborSerializer.CborSerializer.encodeUnsignedInteger(NFT_FORMAT_VERSION),
|
|
10164
|
+
import_CborSerializer.CborSerializer.encodeUnsignedInteger(import_NetworkId.NetworkId.fromId(context.networkId).id),
|
|
10165
|
+
import_CborSerializer.CborSerializer.encodeByteString(context.recipientPredicate),
|
|
10166
|
+
import_CborSerializer.CborSerializer.encodeByteString(context.tokenId),
|
|
10167
|
+
import_CborSerializer.CborSerializer.encodeByteString(context.tokenType),
|
|
10151
10168
|
import_CborSerializer.CborSerializer.encodeByteString(payload)
|
|
10152
10169
|
);
|
|
10153
10170
|
return new import_DataHasher.DataHasher(import_HashAlgorithm.HashAlgorithm.SHA256).update(preimage).digest();
|
|
10154
10171
|
}
|
|
10155
|
-
async function verifyNftSignature(signed,
|
|
10172
|
+
async function verifyNftSignature(signed, context) {
|
|
10156
10173
|
try {
|
|
10157
10174
|
if (!import_SigningService.SigningService.isPublicKeyValid(signed.creator)) return "invalid";
|
|
10158
10175
|
const signature = import_Signature.Signature.decode(signed.signature);
|
|
10159
|
-
const digest = await nftSignedDigest(
|
|
10176
|
+
const digest = await nftSignedDigest(context, signed.payload);
|
|
10160
10177
|
return await import_SigningService.SigningService.verifyWithPublicKey(digest, signature, signed.creator) ? "valid" : "invalid";
|
|
10161
10178
|
} catch {
|
|
10162
10179
|
return "invalid";
|
|
@@ -10287,8 +10304,8 @@ function assertMintableData(data) {
|
|
|
10287
10304
|
function nftRecipientCbor(pubkey) {
|
|
10288
10305
|
return import_EncodedPredicate.EncodedPredicate.fromPredicate(import_SignaturePredicate.SignaturePredicate.create(pubkey)).toCBOR();
|
|
10289
10306
|
}
|
|
10290
|
-
async function signPayload(deps, payload,
|
|
10291
|
-
const digest = await nftSignedDigest(
|
|
10307
|
+
async function signPayload(deps, payload, context) {
|
|
10308
|
+
const digest = await nftSignedDigest(context, payload);
|
|
10292
10309
|
const signature = await deps.signingService.sign(digest);
|
|
10293
10310
|
return encodeNftSigned(deps.signingService.publicKey, payload, signature.encode());
|
|
10294
10311
|
}
|
|
@@ -10297,31 +10314,41 @@ async function planNftMint(deps, params) {
|
|
|
10297
10314
|
const tokenType = new import_TokenType.TokenType(params.tokenType).bytes;
|
|
10298
10315
|
const salt = import_TokenSalt.TokenSalt.generate();
|
|
10299
10316
|
const tokenId = await import_TokenId.TokenId.fromSalt(deps.networkId, salt);
|
|
10300
|
-
const data = params.sign ? await signPayload(deps, payload,
|
|
10317
|
+
const data = params.sign ? await signPayload(deps, payload, {
|
|
10318
|
+
networkId: deps.networkId.id,
|
|
10319
|
+
recipientPredicate: nftRecipientCbor(params.recipientPubkey),
|
|
10320
|
+
tokenId: tokenId.bytes,
|
|
10321
|
+
tokenType
|
|
10322
|
+
}) : payload;
|
|
10301
10323
|
assertMintableData(data);
|
|
10302
10324
|
return { data, salt: salt.toBytes(), tokenType, tokenId: import_HexConverter.HexConverter.encode(tokenId.bytes) };
|
|
10303
10325
|
}
|
|
10304
|
-
async function verifyAgainst(signed,
|
|
10326
|
+
async function verifyAgainst(signed, genesisContext) {
|
|
10305
10327
|
try {
|
|
10306
|
-
return await verifyNftSignature(signed,
|
|
10328
|
+
return await verifyNftSignature(signed, genesisContext());
|
|
10307
10329
|
} catch {
|
|
10308
10330
|
return "invalid";
|
|
10309
10331
|
}
|
|
10310
10332
|
}
|
|
10311
|
-
async function readNftData(data,
|
|
10333
|
+
async function readNftData(data, genesisContext) {
|
|
10312
10334
|
const parsed = parseNftPayload(data);
|
|
10313
10335
|
if (parsed === null) return null;
|
|
10314
10336
|
if (parsed.signed === null) return { content: parsed.content, creator: null, signature: "unsigned" };
|
|
10315
10337
|
return {
|
|
10316
10338
|
content: parsed.content,
|
|
10317
10339
|
creator: import_HexConverter.HexConverter.encode(parsed.signed.creator),
|
|
10318
|
-
signature: await verifyAgainst(parsed.signed,
|
|
10340
|
+
signature: await verifyAgainst(parsed.signed, genesisContext)
|
|
10319
10341
|
};
|
|
10320
10342
|
}
|
|
10321
10343
|
async function readTokenNft(token) {
|
|
10322
10344
|
try {
|
|
10323
10345
|
const { genesis } = token.sdkToken;
|
|
10324
|
-
return await readNftData(genesis.data,
|
|
10346
|
+
return await readNftData(genesis.data, () => ({
|
|
10347
|
+
networkId: genesis.networkId.id,
|
|
10348
|
+
recipientPredicate: genesis.recipient.toCBOR(),
|
|
10349
|
+
tokenId: genesis.tokenId.bytes,
|
|
10350
|
+
tokenType: genesis.tokenType.bytes
|
|
10351
|
+
}));
|
|
10325
10352
|
} catch {
|
|
10326
10353
|
return null;
|
|
10327
10354
|
}
|