@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/connect/index.cjs
CHANGED
|
@@ -43,6 +43,8 @@ __export(connect_exports, {
|
|
|
43
43
|
hasMethodPermission: () => hasMethodPermission,
|
|
44
44
|
isAutoPushedEvent: () => isAutoPushedEvent,
|
|
45
45
|
isSphereConnectMessage: () => isSphereConnectMessage,
|
|
46
|
+
nftContentFromWire: () => nftContentFromWire,
|
|
47
|
+
nftContentToWire: () => nftContentToWire,
|
|
46
48
|
validatePermissions: () => validatePermissions
|
|
47
49
|
});
|
|
48
50
|
module.exports = __toCommonJS(connect_exports);
|
|
@@ -291,7 +293,7 @@ var HOST_READY_TIMEOUT = 3e4;
|
|
|
291
293
|
|
|
292
294
|
// connect/protocol.ts
|
|
293
295
|
var SPHERE_CONNECT_NAMESPACE = "sphere-connect";
|
|
294
|
-
var SPHERE_CONNECT_VERSION = "2.
|
|
296
|
+
var SPHERE_CONNECT_VERSION = "2.3";
|
|
295
297
|
var DEFAULT_MIN_CLIENT_SDK_VERSION = "0.14.1-0";
|
|
296
298
|
var RPC_METHODS = {
|
|
297
299
|
GET_IDENTITY: "sphere_getIdentity",
|
|
@@ -318,7 +320,9 @@ var INTENT_ACTIONS = {
|
|
|
318
320
|
MINT: "mint",
|
|
319
321
|
// #777: params { to, tokenId, memo? }. Named NFT rather than 'send_token':
|
|
320
322
|
// coins are tokens too, so 'token' does not say which kind moves.
|
|
321
|
-
SEND_NFT: "send_nft"
|
|
323
|
+
SEND_NFT: "send_nft",
|
|
324
|
+
// Connect 2.3: params MintNftIntentParams, result MintNftIntentResult (connect/nft-wire.ts).
|
|
325
|
+
MINT_NFT: "mint_nft"
|
|
322
326
|
};
|
|
323
327
|
var ERROR_CODES = {
|
|
324
328
|
// Standard JSON-RPC
|
|
@@ -452,7 +456,7 @@ function checkCompatibility(input) {
|
|
|
452
456
|
}
|
|
453
457
|
|
|
454
458
|
// connect/version.ts
|
|
455
|
-
var SDK_VERSION = "0.17.2-dev.
|
|
459
|
+
var SDK_VERSION = "0.17.2-dev.3";
|
|
456
460
|
|
|
457
461
|
// connect/permissions.ts
|
|
458
462
|
var PERMISSION_SCOPES = {
|
|
@@ -470,7 +474,9 @@ var PERMISSION_SCOPES = {
|
|
|
470
474
|
SIGN_REQUEST: "sign:request",
|
|
471
475
|
MINT_REQUEST: "mint:request",
|
|
472
476
|
/** #777: moving a coinless token (an NFT). Distinct from transfer:request. */
|
|
473
|
-
NFT_TRANSFER: "nft:transfer"
|
|
477
|
+
NFT_TRANSFER: "nft:transfer",
|
|
478
|
+
/** Minting an NFT signs dApp-chosen content as the user; mint:request and nft:transfer do not imply it. */
|
|
479
|
+
NFT_MINT: "nft:mint"
|
|
474
480
|
};
|
|
475
481
|
var ALL_PERMISSIONS = Object.values(PERMISSION_SCOPES);
|
|
476
482
|
var DEFAULT_PERMISSIONS = [
|
|
@@ -498,7 +504,8 @@ var INTENT_PERMISSIONS = {
|
|
|
498
504
|
[INTENT_ACTIONS.RECEIVE]: PERMISSION_SCOPES.IDENTITY_READ,
|
|
499
505
|
[INTENT_ACTIONS.SIGN_MESSAGE]: PERMISSION_SCOPES.SIGN_REQUEST,
|
|
500
506
|
[INTENT_ACTIONS.MINT]: PERMISSION_SCOPES.MINT_REQUEST,
|
|
501
|
-
[INTENT_ACTIONS.SEND_NFT]: PERMISSION_SCOPES.NFT_TRANSFER
|
|
507
|
+
[INTENT_ACTIONS.SEND_NFT]: PERMISSION_SCOPES.NFT_TRANSFER,
|
|
508
|
+
[INTENT_ACTIONS.MINT_NFT]: PERMISSION_SCOPES.NFT_MINT
|
|
502
509
|
};
|
|
503
510
|
function hasMethodPermission(granted, method) {
|
|
504
511
|
const required = METHOD_PERMISSIONS[method];
|
|
@@ -778,6 +785,7 @@ var CHANNEL_ONLY_CODES = /* @__PURE__ */ new Set([
|
|
|
778
785
|
ERROR_CODES.WALLET_LOCKED,
|
|
779
786
|
ERROR_CODES.NOT_CONNECTED
|
|
780
787
|
]);
|
|
788
|
+
var ALWAYS_ASK_INTENTS = /* @__PURE__ */ new Set([INTENT_ACTIONS.MINT_NFT]);
|
|
781
789
|
var DEFAULT_REQUEST_DEADLINE_MS = 25e3;
|
|
782
790
|
var DEFAULT_INTENT_DEADLINE_MS = 18e4;
|
|
783
791
|
var DEFAULT_HANDSHAKE_DEADLINE_MS = 12e4;
|
|
@@ -863,8 +871,11 @@ var ConnectHost = class {
|
|
|
863
871
|
getSession() {
|
|
864
872
|
return this.session;
|
|
865
873
|
}
|
|
866
|
-
/** Register an auto-approve handler for an intent action (session-scoped). */
|
|
874
|
+
/** Register an auto-approve handler for an intent action (session-scoped). Throws for an intent that always asks the user. */
|
|
867
875
|
setIntentAutoApprove(action, handler) {
|
|
876
|
+
if (ALWAYS_ASK_INTENTS.has(action)) {
|
|
877
|
+
throw new SphereError(`Intent ${action} always asks the user and cannot be auto-approved`, "INVALID_CONFIG");
|
|
878
|
+
}
|
|
868
879
|
this.autoApprovedIntents.set(action, handler);
|
|
869
880
|
}
|
|
870
881
|
/** Remove auto-approve for an intent action. */
|
|
@@ -1353,7 +1364,7 @@ var ConnectHost = class {
|
|
|
1353
1364
|
signal: entry.controller.signal
|
|
1354
1365
|
};
|
|
1355
1366
|
try {
|
|
1356
|
-
const autoHandler = this.autoApprovedIntents.get(msg.action);
|
|
1367
|
+
const autoHandler = ALWAYS_ASK_INTENTS.has(msg.action) ? void 0 : this.autoApprovedIntents.get(msg.action);
|
|
1357
1368
|
const response = autoHandler ? await autoHandler(msg.action, msg.params, session) : await this.config.onIntent(msg.action, msg.params, session, ctx);
|
|
1358
1369
|
if (!this.inFlight.settle(msg.id)) return;
|
|
1359
1370
|
if (response.error) {
|
|
@@ -1367,7 +1378,8 @@ var ConnectHost = class {
|
|
|
1367
1378
|
this.sendIntentError(
|
|
1368
1379
|
msg.id,
|
|
1369
1380
|
asserts ? ERROR_CODES.INTENT_OUTCOME_UNKNOWN : response.error.code,
|
|
1370
|
-
asserts ? INTENT_UNKNOWN_MESSAGE : response.error.message
|
|
1381
|
+
asserts ? INTENT_UNKNOWN_MESSAGE : response.error.message,
|
|
1382
|
+
asserts ? void 0 : response.error.data
|
|
1371
1383
|
);
|
|
1372
1384
|
} else {
|
|
1373
1385
|
this.sendIntentResult(msg.id, response.result);
|
|
@@ -2050,4 +2062,186 @@ var ConnectClient = class {
|
|
|
2050
2062
|
this.locked = false;
|
|
2051
2063
|
}
|
|
2052
2064
|
};
|
|
2065
|
+
|
|
2066
|
+
// core/base64.ts
|
|
2067
|
+
var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
2068
|
+
var INVALID = 255;
|
|
2069
|
+
var SEXTETS = new Uint8Array(128).fill(INVALID);
|
|
2070
|
+
for (let i = 0; i < ALPHABET.length; i++) SEXTETS[ALPHABET.charCodeAt(i)] = i;
|
|
2071
|
+
function base64Encode(bytes) {
|
|
2072
|
+
let out = "";
|
|
2073
|
+
for (let i = 0; i < bytes.length; i += 3) {
|
|
2074
|
+
const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;
|
|
2075
|
+
const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;
|
|
2076
|
+
const triple = bytes[i] << 16 | b1 << 8 | b2;
|
|
2077
|
+
out += ALPHABET[triple >> 18] + ALPHABET[triple >> 12 & 63];
|
|
2078
|
+
out += i + 1 < bytes.length ? ALPHABET[triple >> 6 & 63] : "=";
|
|
2079
|
+
out += i + 2 < bytes.length ? ALPHABET[triple & 63] : "=";
|
|
2080
|
+
}
|
|
2081
|
+
return out;
|
|
2082
|
+
}
|
|
2083
|
+
function base64DecodeCanonical(text) {
|
|
2084
|
+
if (text.length % 4 !== 0) return null;
|
|
2085
|
+
const padding = text.endsWith("==") ? 2 : text.endsWith("=") ? 1 : 0;
|
|
2086
|
+
const out = new Uint8Array(text.length / 4 * 3 - padding);
|
|
2087
|
+
let buffer = 0;
|
|
2088
|
+
let bits = 0;
|
|
2089
|
+
let offset = 0;
|
|
2090
|
+
for (let i = 0; i < text.length - padding; i++) {
|
|
2091
|
+
const code = text.charCodeAt(i);
|
|
2092
|
+
const sextet = code < SEXTETS.length ? SEXTETS[code] : INVALID;
|
|
2093
|
+
if (sextet === INVALID) return null;
|
|
2094
|
+
buffer = (buffer << 6 | sextet) & 4095;
|
|
2095
|
+
bits += 6;
|
|
2096
|
+
if (bits >= 8) {
|
|
2097
|
+
bits -= 8;
|
|
2098
|
+
out[offset++] = buffer >> bits;
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
return (buffer & (1 << bits) - 1) === 0 ? out : null;
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2104
|
+
// connect/nft-wire.ts
|
|
2105
|
+
var METADATA_FIELDS = [
|
|
2106
|
+
"kind",
|
|
2107
|
+
"name",
|
|
2108
|
+
"description",
|
|
2109
|
+
"image",
|
|
2110
|
+
"animation_url",
|
|
2111
|
+
"external_url",
|
|
2112
|
+
"attributes",
|
|
2113
|
+
"collection",
|
|
2114
|
+
"collection_id"
|
|
2115
|
+
];
|
|
2116
|
+
var MEDIA_FIELDS = ["kind", "media_type", "bytes"];
|
|
2117
|
+
var LINK_FIELDS = ["kind", "media_type", "uri", "sha256"];
|
|
2118
|
+
var ATTRIBUTE_FIELDS = ["trait_type", "value"];
|
|
2119
|
+
var CONTENT_KINDS = "must be 'metadata', 'media' or 'link'";
|
|
2120
|
+
var MEDIA_REF_KINDS = "must be 'media' or 'link'";
|
|
2121
|
+
function refuse(field, rule) {
|
|
2122
|
+
return new SphereError(`Invalid NFT ${field}: ${rule}`, "VALIDATION_ERROR");
|
|
2123
|
+
}
|
|
2124
|
+
function mediaToWire(media, field) {
|
|
2125
|
+
if (!(media.bytes instanceof Uint8Array)) throw refuse(`${field}.bytes`, "must be a Uint8Array");
|
|
2126
|
+
return { kind: "media", media_type: media.media_type, bytes: base64Encode(media.bytes) };
|
|
2127
|
+
}
|
|
2128
|
+
function linkToWire(link) {
|
|
2129
|
+
return { kind: "link", media_type: link.media_type, uri: link.uri, sha256: link.sha256 };
|
|
2130
|
+
}
|
|
2131
|
+
function mediaRefToWire(ref, field) {
|
|
2132
|
+
if (ref === null) return null;
|
|
2133
|
+
if (ref?.kind === "media") return mediaToWire(ref, field);
|
|
2134
|
+
if (ref?.kind === "link") return linkToWire(ref);
|
|
2135
|
+
throw refuse(`${field}.kind`, MEDIA_REF_KINDS);
|
|
2136
|
+
}
|
|
2137
|
+
function metadataToWire(metadata) {
|
|
2138
|
+
return {
|
|
2139
|
+
kind: "metadata",
|
|
2140
|
+
name: metadata.name,
|
|
2141
|
+
description: metadata.description,
|
|
2142
|
+
image: mediaRefToWire(metadata.image, "content.image"),
|
|
2143
|
+
animation_url: mediaRefToWire(metadata.animation_url, "content.animation_url"),
|
|
2144
|
+
external_url: metadata.external_url,
|
|
2145
|
+
attributes: metadata.attributes.map(({ trait_type, value }) => ({ trait_type, value })),
|
|
2146
|
+
collection: metadata.collection,
|
|
2147
|
+
collection_id: metadata.collection_id
|
|
2148
|
+
};
|
|
2149
|
+
}
|
|
2150
|
+
function nftContentToWire(content) {
|
|
2151
|
+
switch (content?.kind) {
|
|
2152
|
+
case "metadata":
|
|
2153
|
+
return metadataToWire(content);
|
|
2154
|
+
case "media":
|
|
2155
|
+
return mediaToWire(content, "content");
|
|
2156
|
+
case "link":
|
|
2157
|
+
return linkToWire(content);
|
|
2158
|
+
default:
|
|
2159
|
+
throw refuse("content.kind", CONTENT_KINDS);
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
function recordAt(value, field, rule = "must be an object") {
|
|
2163
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw refuse(field, rule);
|
|
2164
|
+
return value;
|
|
2165
|
+
}
|
|
2166
|
+
function requireExactFields(record, field, fields) {
|
|
2167
|
+
const missing = fields.find((name) => !Object.prototype.hasOwnProperty.call(record, name));
|
|
2168
|
+
if (missing !== void 0) throw refuse(`${field}.${missing}`, "is missing \u2014 an absent optional field is null");
|
|
2169
|
+
const extra = Object.keys(record).find((name) => !fields.includes(name));
|
|
2170
|
+
if (extra !== void 0) throw refuse(`${field}.${extra}`, "is not a field of this item");
|
|
2171
|
+
}
|
|
2172
|
+
function stringAt(record, field, name) {
|
|
2173
|
+
const value = record[name];
|
|
2174
|
+
if (typeof value !== "string") throw refuse(`${field}.${name}`, "must be a string");
|
|
2175
|
+
return value;
|
|
2176
|
+
}
|
|
2177
|
+
function optionalStringAt(record, field, name) {
|
|
2178
|
+
const value = record[name];
|
|
2179
|
+
if (value === null) return null;
|
|
2180
|
+
if (typeof value !== "string") throw refuse(`${field}.${name}`, "must be a string or null");
|
|
2181
|
+
return value;
|
|
2182
|
+
}
|
|
2183
|
+
function mediaFromWire(record, field) {
|
|
2184
|
+
requireExactFields(record, field, MEDIA_FIELDS);
|
|
2185
|
+
const mediaType = stringAt(record, field, "media_type");
|
|
2186
|
+
const bytes = base64DecodeCanonical(stringAt(record, field, "bytes"));
|
|
2187
|
+
if (bytes === null) throw refuse(`${field}.bytes`, "must be canonical standard base64 with padding (RFC 4648 \xA74)");
|
|
2188
|
+
return { kind: "media", media_type: mediaType, bytes };
|
|
2189
|
+
}
|
|
2190
|
+
function linkFromWire(record, field) {
|
|
2191
|
+
requireExactFields(record, field, LINK_FIELDS);
|
|
2192
|
+
return {
|
|
2193
|
+
kind: "link",
|
|
2194
|
+
media_type: stringAt(record, field, "media_type"),
|
|
2195
|
+
uri: stringAt(record, field, "uri"),
|
|
2196
|
+
sha256: stringAt(record, field, "sha256")
|
|
2197
|
+
};
|
|
2198
|
+
}
|
|
2199
|
+
function mediaRefFromWire(value, field) {
|
|
2200
|
+
if (value === null) return null;
|
|
2201
|
+
const record = recordAt(value, field, "must be a media or link object, or null");
|
|
2202
|
+
if (record.kind === "media") return mediaFromWire(record, field);
|
|
2203
|
+
if (record.kind === "link") return linkFromWire(record, field);
|
|
2204
|
+
throw refuse(`${field}.kind`, MEDIA_REF_KINDS);
|
|
2205
|
+
}
|
|
2206
|
+
function attributeFromWire(value, field) {
|
|
2207
|
+
const record = recordAt(value, field);
|
|
2208
|
+
requireExactFields(record, field, ATTRIBUTE_FIELDS);
|
|
2209
|
+
const traitType = stringAt(record, field, "trait_type");
|
|
2210
|
+
const attributeValue = record.value;
|
|
2211
|
+
if (typeof attributeValue !== "string" && typeof attributeValue !== "number") {
|
|
2212
|
+
throw refuse(`${field}.value`, "must be a string or a number");
|
|
2213
|
+
}
|
|
2214
|
+
return { trait_type: traitType, value: attributeValue };
|
|
2215
|
+
}
|
|
2216
|
+
function attributesFromWire(value, field) {
|
|
2217
|
+
if (!Array.isArray(value)) throw refuse(field, "must be an array \u2014 [] when there are none");
|
|
2218
|
+
return Array.from(value, (entry, index) => attributeFromWire(entry, `${field}[${index}]`));
|
|
2219
|
+
}
|
|
2220
|
+
function metadataFromWire(record) {
|
|
2221
|
+
requireExactFields(record, "content", METADATA_FIELDS);
|
|
2222
|
+
return {
|
|
2223
|
+
kind: "metadata",
|
|
2224
|
+
name: stringAt(record, "content", "name"),
|
|
2225
|
+
description: optionalStringAt(record, "content", "description"),
|
|
2226
|
+
image: mediaRefFromWire(record.image, "content.image"),
|
|
2227
|
+
animation_url: mediaRefFromWire(record.animation_url, "content.animation_url"),
|
|
2228
|
+
external_url: optionalStringAt(record, "content", "external_url"),
|
|
2229
|
+
attributes: attributesFromWire(record.attributes, "content.attributes"),
|
|
2230
|
+
collection: optionalStringAt(record, "content", "collection"),
|
|
2231
|
+
collection_id: optionalStringAt(record, "content", "collection_id")
|
|
2232
|
+
};
|
|
2233
|
+
}
|
|
2234
|
+
function nftContentFromWire(wire) {
|
|
2235
|
+
const record = recordAt(wire, "content");
|
|
2236
|
+
switch (record.kind) {
|
|
2237
|
+
case "metadata":
|
|
2238
|
+
return metadataFromWire(record);
|
|
2239
|
+
case "media":
|
|
2240
|
+
return mediaFromWire(record, "content");
|
|
2241
|
+
case "link":
|
|
2242
|
+
return linkFromWire(record, "content");
|
|
2243
|
+
default:
|
|
2244
|
+
throw refuse("content.kind", CONTENT_KINDS);
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2053
2247
|
//# sourceMappingURL=index.cjs.map
|