@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/index.cjs
CHANGED
|
@@ -50,6 +50,7 @@ __export(index_exports, {
|
|
|
50
50
|
LIMITS: () => LIMITS,
|
|
51
51
|
MarketModule: () => MarketModule,
|
|
52
52
|
NETWORKS: () => NETWORKS,
|
|
53
|
+
NFT_DOCUMENT_MEDIA_TYPE: () => NFT_DOCUMENT_MEDIA_TYPE,
|
|
53
54
|
NFT_LINK_TAG: () => NFT_LINK_TAG,
|
|
54
55
|
NFT_MAX_PAYLOAD_BYTES: () => NFT_MAX_PAYLOAD_BYTES,
|
|
55
56
|
NFT_MEDIA_TAG: () => NFT_MEDIA_TAG,
|
|
@@ -128,6 +129,7 @@ __export(index_exports, {
|
|
|
128
129
|
identityFromMnemonicSync: () => identityFromMnemonicSync,
|
|
129
130
|
initSphere: () => initSphere,
|
|
130
131
|
isKnownToken: () => isKnownToken,
|
|
132
|
+
isNftDocumentLink: () => isNftDocumentLink,
|
|
131
133
|
isPhoneNumber: () => import_nostr_js_sdk5.isPhoneNumber,
|
|
132
134
|
isPossiblyCommittedSendOutcome: () => isPossiblyCommittedSendOutcome,
|
|
133
135
|
isSphereError: () => isSphereError,
|
|
@@ -145,6 +147,7 @@ __export(index_exports, {
|
|
|
145
147
|
normalizeNametag: () => import_nostr_js_sdk5.normalizeNametag,
|
|
146
148
|
parseAddress: () => parseAddress,
|
|
147
149
|
parseAndDecryptWalletText: () => parseAndDecryptWalletText,
|
|
150
|
+
parseNftDocument: () => parseNftDocument,
|
|
148
151
|
parseNftPayload: () => parseNftPayload,
|
|
149
152
|
parseTokenAmount: () => parseTokenAmount,
|
|
150
153
|
parseWalletText: () => parseWalletText,
|
|
@@ -9937,7 +9940,8 @@ var NFT_MEDIA_TAG = 39053n;
|
|
|
9937
9940
|
var NFT_LINK_TAG = 39054n;
|
|
9938
9941
|
var NFT_SIGNED_TAG = 39055n;
|
|
9939
9942
|
var NFT_FORMAT_VERSION = 1n;
|
|
9940
|
-
var
|
|
9943
|
+
var NFT_DOCUMENT_MEDIA_TYPE = "application/vnd.unicity.nft+cbor";
|
|
9944
|
+
var METADATA_ARITY = 9;
|
|
9941
9945
|
var MEDIA_ARITY = 3;
|
|
9942
9946
|
var LINK_ARITY = 4;
|
|
9943
9947
|
var SIGNED_ARITY = 4;
|
|
@@ -9945,12 +9949,15 @@ var CREATOR_BYTES = 33;
|
|
|
9945
9949
|
var SIGNATURE_BYTES = 65;
|
|
9946
9950
|
var MAX_URI_LENGTH = 2048;
|
|
9947
9951
|
var LINK_SCHEMES = ["https://", "ipfs://", "ar://"];
|
|
9948
|
-
var SIGNED_DOMAIN = "
|
|
9952
|
+
var SIGNED_DOMAIN = new TextEncoder().encode("UNICITY_NFT_SIGNED");
|
|
9949
9953
|
var MEDIA_TYPE_PATTERN = /^[a-z0-9][a-z0-9!#$&^_.+-]{0,126}\/[a-z0-9][a-z0-9!#$&^_.+-]{0,126}$/;
|
|
9950
9954
|
var SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/i;
|
|
9955
|
+
var COLLECTION_ID_PATTERN = /^(?:[0-9a-f]{2}){1,64}$/i;
|
|
9951
9956
|
var LONE_SURROGATE = /\p{Cs}/u;
|
|
9952
9957
|
var CBOR_MAJOR_TYPE_MASK = 224;
|
|
9953
9958
|
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";
|
|
9959
|
+
var COLLECTION_ID_RULE = "must be null or 1\u201364 bytes as even-length hex (2\u2013128 characters)";
|
|
9960
|
+
var DOCUMENT_AS_MEDIA_RULE = `must not be ${NFT_DOCUMENT_MEDIA_TYPE}: a document link is a token's content, never media`;
|
|
9954
9961
|
var UTF8 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
|
|
9955
9962
|
function refuse(field, rule, cause) {
|
|
9956
9963
|
return new SphereError(`Invalid NFT ${field}: ${rule}`, "VALIDATION_ERROR", cause);
|
|
@@ -9962,6 +9969,7 @@ var fieldName = (prefix, name) => prefix === "" ? name : `${prefix}.${name}`;
|
|
|
9962
9969
|
var isText = (value) => typeof value === "string" && value.length > 0 && !LONE_SURROGATE.test(value);
|
|
9963
9970
|
var isBytes3 = (value, length) => value instanceof Uint8Array && (length === void 0 ? value.length > 0 : value.length === length);
|
|
9964
9971
|
var isMediaType = (value) => typeof value === "string" && MEDIA_TYPE_PATTERN.test(value);
|
|
9972
|
+
var isCollectionId = (value) => typeof value === "string" && COLLECTION_ID_PATTERN.test(value);
|
|
9965
9973
|
var isAttributeValue = (value) => typeof value === "number" ? Number.isSafeInteger(value) : isText(value);
|
|
9966
9974
|
function hasSpaceOrControl(value) {
|
|
9967
9975
|
for (let i = 0; i < value.length; i++) {
|
|
@@ -10004,8 +10012,9 @@ function checkLink(prefix, link) {
|
|
|
10004
10012
|
function checkMediaRef(field, ref) {
|
|
10005
10013
|
if (ref === null) return;
|
|
10006
10014
|
if (ref?.kind === "media") return checkMedia(field, ref);
|
|
10007
|
-
if (ref?.kind
|
|
10008
|
-
|
|
10015
|
+
if (ref?.kind !== "link") throw refuse(field, "must be an NftMedia, an NftLink or null");
|
|
10016
|
+
checkLink(field, ref);
|
|
10017
|
+
ensure(!isNftDocumentLink(ref), fieldName(field, "media_type"), DOCUMENT_AS_MEDIA_RULE);
|
|
10009
10018
|
}
|
|
10010
10019
|
function checkAttributes(attributes) {
|
|
10011
10020
|
ensure(Array.isArray(attributes), "attributes", "must be an array \u2014 [] when there are none");
|
|
@@ -10022,6 +10031,7 @@ function checkMetadata(metadata) {
|
|
|
10022
10031
|
checkOptionalText("external_url", metadata.external_url);
|
|
10023
10032
|
checkAttributes(metadata.attributes);
|
|
10024
10033
|
checkOptionalText("collection", metadata.collection);
|
|
10034
|
+
ensure(metadata.collection_id === null || isCollectionId(metadata.collection_id), "collection_id", COLLECTION_ID_RULE);
|
|
10025
10035
|
}
|
|
10026
10036
|
function checkContent(content) {
|
|
10027
10037
|
switch (content?.kind) {
|
|
@@ -10079,6 +10089,7 @@ function arrayCbor(items) {
|
|
|
10079
10089
|
}
|
|
10080
10090
|
return out;
|
|
10081
10091
|
}
|
|
10092
|
+
var optionalHexBytes = (value) => import_CborSerializer.CborSerializer.encodeNullable(value, (hex) => import_CborSerializer.CborSerializer.encodeByteString(import_HexConverter.HexConverter.decode(hex.toLowerCase())));
|
|
10082
10093
|
function metadataCbor(metadata) {
|
|
10083
10094
|
return versioned(
|
|
10084
10095
|
NFT_METADATA_TAG,
|
|
@@ -10088,7 +10099,8 @@ function metadataCbor(metadata) {
|
|
|
10088
10099
|
mediaRefCbor(metadata.animation_url),
|
|
10089
10100
|
optionalText(metadata.external_url),
|
|
10090
10101
|
arrayCbor(metadata.attributes.map(attributeCbor)),
|
|
10091
|
-
optionalText(metadata.collection)
|
|
10102
|
+
optionalText(metadata.collection),
|
|
10103
|
+
optionalHexBytes(metadata.collection_id)
|
|
10092
10104
|
);
|
|
10093
10105
|
}
|
|
10094
10106
|
function encodeNftContent(content) {
|
|
@@ -10146,13 +10158,14 @@ function decodeMedia(body) {
|
|
|
10146
10158
|
const [, mediaType, bytes] = versionedFields(body, MEDIA_ARITY);
|
|
10147
10159
|
return { kind: "media", media_type: decodeText(mediaType), bytes: import_CborDeserializer.CborDeserializer.decodeByteString(bytes) };
|
|
10148
10160
|
}
|
|
10161
|
+
var decodeHex = (item) => import_HexConverter.HexConverter.encode(import_CborDeserializer.CborDeserializer.decodeByteString(item));
|
|
10149
10162
|
function decodeLink(body) {
|
|
10150
10163
|
const [, mediaType, uri, digest] = versionedFields(body, LINK_ARITY);
|
|
10151
10164
|
return {
|
|
10152
10165
|
kind: "link",
|
|
10153
10166
|
media_type: decodeText(mediaType),
|
|
10154
10167
|
uri: decodeText(uri),
|
|
10155
|
-
sha256:
|
|
10168
|
+
sha256: decodeHex(digest)
|
|
10156
10169
|
};
|
|
10157
10170
|
}
|
|
10158
10171
|
function decodeMetadata(body) {
|
|
@@ -10165,7 +10178,8 @@ function decodeMetadata(body) {
|
|
|
10165
10178
|
animation_url: decodeMediaRef("animation_url", fields[4]),
|
|
10166
10179
|
external_url: decodeOptionalText(fields[5]),
|
|
10167
10180
|
attributes: decodeAttributes(fields[6]),
|
|
10168
|
-
collection: decodeOptionalText(fields[7])
|
|
10181
|
+
collection: decodeOptionalText(fields[7]),
|
|
10182
|
+
collection_id: import_CborDeserializer.CborDeserializer.decodeNullable(fields[8], decodeHex)
|
|
10169
10183
|
};
|
|
10170
10184
|
}
|
|
10171
10185
|
var MEDIA_REF_DECODERS = /* @__PURE__ */ new Map([
|
|
@@ -10177,6 +10191,10 @@ var UNSIGNED_DECODERS = /* @__PURE__ */ new Map([
|
|
|
10177
10191
|
[NFT_MEDIA_TAG, decodeMedia],
|
|
10178
10192
|
[NFT_LINK_TAG, decodeLink]
|
|
10179
10193
|
]);
|
|
10194
|
+
var DOCUMENT_DECODERS = /* @__PURE__ */ new Map([
|
|
10195
|
+
[NFT_METADATA_TAG, decodeMetadata],
|
|
10196
|
+
[NFT_MEDIA_TAG, decodeMedia]
|
|
10197
|
+
]);
|
|
10180
10198
|
function decodeBody(decoders, field, tag, body) {
|
|
10181
10199
|
const decode = decoders.get(tag);
|
|
10182
10200
|
if (decode === void 0) throw refuse(field, `tag ${tag} is not allowed here`);
|
|
@@ -10211,20 +10229,35 @@ function parseNftPayload(data) {
|
|
|
10211
10229
|
return null;
|
|
10212
10230
|
}
|
|
10213
10231
|
}
|
|
10214
|
-
function
|
|
10232
|
+
function parseNftDocument(bytes) {
|
|
10233
|
+
try {
|
|
10234
|
+
const document = decodeItem(DOCUMENT_DECODERS, "document", bytes);
|
|
10235
|
+
checkContent(document);
|
|
10236
|
+
return document;
|
|
10237
|
+
} catch {
|
|
10238
|
+
return null;
|
|
10239
|
+
}
|
|
10240
|
+
}
|
|
10241
|
+
function isNftDocumentLink(content) {
|
|
10242
|
+
return content?.kind === "link" && content.media_type === NFT_DOCUMENT_MEDIA_TYPE;
|
|
10243
|
+
}
|
|
10244
|
+
function nftSignedDigest(context, payload) {
|
|
10215
10245
|
const preimage = import_CborSerializer.CborSerializer.encodeArray(
|
|
10216
|
-
import_CborSerializer.CborSerializer.
|
|
10217
|
-
|
|
10218
|
-
|
|
10246
|
+
import_CborSerializer.CborSerializer.encodeByteString(SIGNED_DOMAIN),
|
|
10247
|
+
import_CborSerializer.CborSerializer.encodeUnsignedInteger(NFT_FORMAT_VERSION),
|
|
10248
|
+
import_CborSerializer.CborSerializer.encodeUnsignedInteger(import_NetworkId.NetworkId.fromId(context.networkId).id),
|
|
10249
|
+
import_CborSerializer.CborSerializer.encodeByteString(context.recipientPredicate),
|
|
10250
|
+
import_CborSerializer.CborSerializer.encodeByteString(context.tokenId),
|
|
10251
|
+
import_CborSerializer.CborSerializer.encodeByteString(context.tokenType),
|
|
10219
10252
|
import_CborSerializer.CborSerializer.encodeByteString(payload)
|
|
10220
10253
|
);
|
|
10221
10254
|
return new import_DataHasher.DataHasher(import_HashAlgorithm.HashAlgorithm.SHA256).update(preimage).digest();
|
|
10222
10255
|
}
|
|
10223
|
-
async function verifyNftSignature(signed,
|
|
10256
|
+
async function verifyNftSignature(signed, context) {
|
|
10224
10257
|
try {
|
|
10225
10258
|
if (!import_SigningService.SigningService.isPublicKeyValid(signed.creator)) return "invalid";
|
|
10226
10259
|
const signature = import_Signature.Signature.decode(signed.signature);
|
|
10227
|
-
const digest = await nftSignedDigest(
|
|
10260
|
+
const digest = await nftSignedDigest(context, signed.payload);
|
|
10228
10261
|
return await import_SigningService.SigningService.verifyWithPublicKey(digest, signature, signed.creator) ? "valid" : "invalid";
|
|
10229
10262
|
} catch {
|
|
10230
10263
|
return "invalid";
|
|
@@ -10358,8 +10391,8 @@ function assertMintableData(data) {
|
|
|
10358
10391
|
function nftRecipientCbor(pubkey) {
|
|
10359
10392
|
return import_EncodedPredicate.EncodedPredicate.fromPredicate(import_SignaturePredicate.SignaturePredicate.create(pubkey)).toCBOR();
|
|
10360
10393
|
}
|
|
10361
|
-
async function signPayload(deps, payload,
|
|
10362
|
-
const digest = await nftSignedDigest(
|
|
10394
|
+
async function signPayload(deps, payload, context) {
|
|
10395
|
+
const digest = await nftSignedDigest(context, payload);
|
|
10363
10396
|
const signature = await deps.signingService.sign(digest);
|
|
10364
10397
|
return encodeNftSigned(deps.signingService.publicKey, payload, signature.encode());
|
|
10365
10398
|
}
|
|
@@ -10368,31 +10401,41 @@ async function planNftMint(deps, params) {
|
|
|
10368
10401
|
const tokenType = new import_TokenType.TokenType(params.tokenType).bytes;
|
|
10369
10402
|
const salt = import_TokenSalt.TokenSalt.generate();
|
|
10370
10403
|
const tokenId = await import_TokenId.TokenId.fromSalt(deps.networkId, salt);
|
|
10371
|
-
const data = params.sign ? await signPayload(deps, payload,
|
|
10404
|
+
const data = params.sign ? await signPayload(deps, payload, {
|
|
10405
|
+
networkId: deps.networkId.id,
|
|
10406
|
+
recipientPredicate: nftRecipientCbor(params.recipientPubkey),
|
|
10407
|
+
tokenId: tokenId.bytes,
|
|
10408
|
+
tokenType
|
|
10409
|
+
}) : payload;
|
|
10372
10410
|
assertMintableData(data);
|
|
10373
10411
|
return { data, salt: salt.toBytes(), tokenType, tokenId: import_HexConverter.HexConverter.encode(tokenId.bytes) };
|
|
10374
10412
|
}
|
|
10375
|
-
async function verifyAgainst(signed,
|
|
10413
|
+
async function verifyAgainst(signed, genesisContext) {
|
|
10376
10414
|
try {
|
|
10377
|
-
return await verifyNftSignature(signed,
|
|
10415
|
+
return await verifyNftSignature(signed, genesisContext());
|
|
10378
10416
|
} catch {
|
|
10379
10417
|
return "invalid";
|
|
10380
10418
|
}
|
|
10381
10419
|
}
|
|
10382
|
-
async function readNftData(data,
|
|
10420
|
+
async function readNftData(data, genesisContext) {
|
|
10383
10421
|
const parsed = parseNftPayload(data);
|
|
10384
10422
|
if (parsed === null) return null;
|
|
10385
10423
|
if (parsed.signed === null) return { content: parsed.content, creator: null, signature: "unsigned" };
|
|
10386
10424
|
return {
|
|
10387
10425
|
content: parsed.content,
|
|
10388
10426
|
creator: import_HexConverter.HexConverter.encode(parsed.signed.creator),
|
|
10389
|
-
signature: await verifyAgainst(parsed.signed,
|
|
10427
|
+
signature: await verifyAgainst(parsed.signed, genesisContext)
|
|
10390
10428
|
};
|
|
10391
10429
|
}
|
|
10392
10430
|
async function readTokenNft(token) {
|
|
10393
10431
|
try {
|
|
10394
10432
|
const { genesis } = token.sdkToken;
|
|
10395
|
-
return await readNftData(genesis.data,
|
|
10433
|
+
return await readNftData(genesis.data, () => ({
|
|
10434
|
+
networkId: genesis.networkId.id,
|
|
10435
|
+
recipientPredicate: genesis.recipient.toCBOR(),
|
|
10436
|
+
tokenId: genesis.tokenId.bytes,
|
|
10437
|
+
tokenType: genesis.tokenType.bytes
|
|
10438
|
+
}));
|
|
10396
10439
|
} catch {
|
|
10397
10440
|
return null;
|
|
10398
10441
|
}
|
|
@@ -20853,6 +20896,7 @@ function addressesMatch(a, b) {
|
|
|
20853
20896
|
LIMITS,
|
|
20854
20897
|
MarketModule,
|
|
20855
20898
|
NETWORKS,
|
|
20899
|
+
NFT_DOCUMENT_MEDIA_TYPE,
|
|
20856
20900
|
NFT_LINK_TAG,
|
|
20857
20901
|
NFT_MAX_PAYLOAD_BYTES,
|
|
20858
20902
|
NFT_MEDIA_TAG,
|
|
@@ -20931,6 +20975,7 @@ function addressesMatch(a, b) {
|
|
|
20931
20975
|
identityFromMnemonicSync,
|
|
20932
20976
|
initSphere,
|
|
20933
20977
|
isKnownToken,
|
|
20978
|
+
isNftDocumentLink,
|
|
20934
20979
|
isPhoneNumber,
|
|
20935
20980
|
isPossiblyCommittedSendOutcome,
|
|
20936
20981
|
isSphereError,
|
|
@@ -20948,6 +20993,7 @@ function addressesMatch(a, b) {
|
|
|
20948
20993
|
normalizeNametag,
|
|
20949
20994
|
parseAddress,
|
|
20950
20995
|
parseAndDecryptWalletText,
|
|
20996
|
+
parseNftDocument,
|
|
20951
20997
|
parseNftPayload,
|
|
20952
20998
|
parseTokenAmount,
|
|
20953
20999
|
parseWalletText,
|