@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.d.cts
CHANGED
|
@@ -34,7 +34,7 @@ declare const HOST_READY_TIMEOUT = 30000;
|
|
|
34
34
|
* JSON-RPC-like message types for wallet ↔ dApp communication.
|
|
35
35
|
*/
|
|
36
36
|
declare const SPHERE_CONNECT_NAMESPACE = "sphere-connect";
|
|
37
|
-
declare const SPHERE_CONNECT_VERSION = "2.
|
|
37
|
+
declare const SPHERE_CONNECT_VERSION = "2.3";
|
|
38
38
|
declare const RPC_METHODS: {
|
|
39
39
|
readonly GET_IDENTITY: "sphere_getIdentity";
|
|
40
40
|
readonly GET_BALANCE: "sphere_getBalance";
|
|
@@ -60,6 +60,7 @@ declare const INTENT_ACTIONS: {
|
|
|
60
60
|
readonly SIGN_MESSAGE: "sign_message";
|
|
61
61
|
readonly MINT: "mint";
|
|
62
62
|
readonly SEND_NFT: "send_nft";
|
|
63
|
+
readonly MINT_NFT: "mint_nft";
|
|
63
64
|
};
|
|
64
65
|
type IntentAction = (typeof INTENT_ACTIONS)[keyof typeof INTENT_ACTIONS];
|
|
65
66
|
declare const ERROR_CODES: {
|
|
@@ -272,6 +273,8 @@ declare const PERMISSION_SCOPES: {
|
|
|
272
273
|
readonly MINT_REQUEST: "mint:request";
|
|
273
274
|
/** #777: moving a coinless token (an NFT). Distinct from transfer:request. */
|
|
274
275
|
readonly NFT_TRANSFER: "nft:transfer";
|
|
276
|
+
/** Minting an NFT signs dApp-chosen content as the user; mint:request and nft:transfer do not imply it. */
|
|
277
|
+
readonly NFT_MINT: "nft:mint";
|
|
275
278
|
};
|
|
276
279
|
type PermissionScope = (typeof PERMISSION_SCOPES)[keyof typeof PERMISSION_SCOPES];
|
|
277
280
|
/** All available permission scopes */
|
|
@@ -371,12 +374,14 @@ interface ConnectHostConfig {
|
|
|
371
374
|
/** Called when dApp sends an intent. Wallet opens corresponding UI.
|
|
372
375
|
* `ctx` (added in Connect 2.1) carries the host-side deadline and an AbortSignal:
|
|
373
376
|
* the wallet MUST dismiss its modal on abort, otherwise the host's own deadline
|
|
374
|
-
* manufactures the double-submit it was added to prevent.
|
|
377
|
+
* manufactures the double-submit it was added to prevent.
|
|
378
|
+
* `error.data` reaches the dApp as `ConnectError.data`, unless the host downgrades the code. */
|
|
375
379
|
onIntent: (action: string, params: Record<string, unknown>, session: ConnectSession, ctx?: IntentContext) => Promise<{
|
|
376
380
|
result?: unknown;
|
|
377
381
|
error?: {
|
|
378
382
|
code: number;
|
|
379
383
|
message: string;
|
|
384
|
+
data?: unknown;
|
|
380
385
|
};
|
|
381
386
|
}>;
|
|
382
387
|
/** Called when dApp explicitly disconnects. Wallet can revoke persisted permissions. */
|
|
@@ -510,12 +515,13 @@ declare class ConnectHost {
|
|
|
510
515
|
};
|
|
511
516
|
/** Get current active session */
|
|
512
517
|
getSession(): ConnectSession | null;
|
|
513
|
-
/** Register an auto-approve handler for an intent action (session-scoped). */
|
|
518
|
+
/** Register an auto-approve handler for an intent action (session-scoped). Throws for an intent that always asks the user. */
|
|
514
519
|
setIntentAutoApprove(action: string, handler: (action: string, params: Record<string, unknown>, session: ConnectSession) => Promise<{
|
|
515
520
|
result?: unknown;
|
|
516
521
|
error?: {
|
|
517
522
|
code: number;
|
|
518
523
|
message: string;
|
|
524
|
+
data?: unknown;
|
|
519
525
|
};
|
|
520
526
|
}>): void;
|
|
521
527
|
/** Remove auto-approve for an intent action. */
|
|
@@ -720,4 +726,75 @@ declare class ConnectClient {
|
|
|
720
726
|
private cleanup;
|
|
721
727
|
}
|
|
722
728
|
|
|
723
|
-
|
|
729
|
+
/** An inline file. */
|
|
730
|
+
interface NftMedia {
|
|
731
|
+
readonly kind: 'media';
|
|
732
|
+
readonly media_type: string;
|
|
733
|
+
readonly bytes: Uint8Array;
|
|
734
|
+
}
|
|
735
|
+
/** A hosted file, pinned by the SHA-256 of its bytes (64 hex; decoded lowercase). */
|
|
736
|
+
interface NftLink {
|
|
737
|
+
readonly kind: 'link';
|
|
738
|
+
readonly media_type: string;
|
|
739
|
+
readonly uri: string;
|
|
740
|
+
readonly sha256: string;
|
|
741
|
+
}
|
|
742
|
+
type NftMediaRef = NftMedia | NftLink;
|
|
743
|
+
interface NftAttribute {
|
|
744
|
+
readonly trait_type: string;
|
|
745
|
+
/** Text, or an integer within ±(2^53 − 1). Decimals and larger numbers are text. */
|
|
746
|
+
readonly value: string | number;
|
|
747
|
+
}
|
|
748
|
+
/** ERC-721 field names; an absent optional field is `null`, never `''`. */
|
|
749
|
+
interface NftMetadata {
|
|
750
|
+
readonly kind: 'metadata';
|
|
751
|
+
readonly name: string;
|
|
752
|
+
readonly description: string | null;
|
|
753
|
+
readonly image: NftMediaRef | null;
|
|
754
|
+
readonly animation_url: NftMediaRef | null;
|
|
755
|
+
readonly external_url: string | null;
|
|
756
|
+
readonly attributes: readonly NftAttribute[];
|
|
757
|
+
readonly collection: string | null;
|
|
758
|
+
/** The collection the item claims: 1–64 bytes as even-length hex (decoded lowercase). Never verified here. */
|
|
759
|
+
readonly collection_id: string | null;
|
|
760
|
+
}
|
|
761
|
+
type NftContent = NftMetadata | NftMedia | NftLink;
|
|
762
|
+
|
|
763
|
+
/** An inline file; `bytes` is standard base64 (RFC 4648 §4, with padding). */
|
|
764
|
+
interface WireNftMedia {
|
|
765
|
+
readonly kind: 'media';
|
|
766
|
+
readonly media_type: string;
|
|
767
|
+
readonly bytes: string;
|
|
768
|
+
}
|
|
769
|
+
interface WireNftMetadata {
|
|
770
|
+
readonly kind: 'metadata';
|
|
771
|
+
readonly name: string;
|
|
772
|
+
readonly description: string | null;
|
|
773
|
+
readonly image: WireNftMedia | NftLink | null;
|
|
774
|
+
readonly animation_url: WireNftMedia | NftLink | null;
|
|
775
|
+
readonly external_url: string | null;
|
|
776
|
+
readonly attributes: readonly NftAttribute[];
|
|
777
|
+
readonly collection: string | null;
|
|
778
|
+
/** Hex, passed through unchanged; `encodeNftContent` judges its value. */
|
|
779
|
+
readonly collection_id: string | null;
|
|
780
|
+
}
|
|
781
|
+
type WireNftContent = WireNftMetadata | WireNftMedia | NftLink;
|
|
782
|
+
/** A type alias, not an interface, so a typed value passes as `ConnectClient.intent` params. */
|
|
783
|
+
type MintNftIntentParams = {
|
|
784
|
+
readonly content: WireNftContent;
|
|
785
|
+
/** Default `true`: the wallet wraps the payload in NftSigned with its chain key as creator. */
|
|
786
|
+
readonly sign?: boolean;
|
|
787
|
+
};
|
|
788
|
+
interface MintNftIntentResult {
|
|
789
|
+
/** 64 lowercase hex. */
|
|
790
|
+
readonly tokenId: string;
|
|
791
|
+
}
|
|
792
|
+
/** `NftContent` → its JSON wire form. Inline bytes become base64; every other field is copied unchanged. */
|
|
793
|
+
declare function nftContentToWire(content: NftContent): WireNftContent;
|
|
794
|
+
/**
|
|
795
|
+
* The wire form → `NftContent`. Checks shape and base64 only, throwing a `SphereError`
|
|
796
|
+
* (`VALIDATION_ERROR`) whose message names the offending field.
|
|
797
|
+
*/
|
|
798
|
+
declare function nftContentFromWire(wire: unknown): NftContent;
|
|
799
|
+
|
|
800
|
+
export { ALL_PERMISSIONS, AUTO_PUSHED_EVENTS, ConnectClient, type ConnectClientConfig, ConnectError, type ConnectEventHandler, ConnectHost, type ConnectHostConfig, type ConnectResult, type ConnectSession, type ConnectTransport, type DAppMetadata, DEFAULT_PERMISSIONS, ERROR_CODES, type ErrorCode, HOST_READY_TIMEOUT, HOST_READY_TYPE, INTENT_ACTIONS, INTENT_PERMISSIONS, type IntentAction, type IntentContext, type LockedRequestContext, METHOD_PERMISSIONS, type MintNftIntentParams, type MintNftIntentResult, type NetworkInfo, type NftAttribute, type NftContent, type NftLink, type NftMedia, type NftMediaRef, type NftMetadata, PERMISSION_SCOPES, type PermissionScope, type PublicIdentity, RPC_METHODS, type RpcMethod, SPHERE_CONNECT_NAMESPACE, SPHERE_CONNECT_VERSION, SPHERE_NETWORKS, type SphereConnectMessage, type SphereEventMessage, type SphereHandshake, type SphereIntentRequest, type SphereIntentResult, type SphereRpcError, type SphereRpcRequest, type SphereRpcResponse, WALLET_EVENTS, type WalletDisconnectedPayload, type WalletEvent, type WalletIdentityChangedPayload, type WalletLockedData, type WalletLockedPayload, type WalletState, type WalletUnlockedPayload, type WireNftContent, type WireNftMedia, type WireNftMetadata, createRequestId, hasIntentPermission, hasMethodPermission, isAutoPushedEvent, isSphereConnectMessage, nftContentFromWire, nftContentToWire, validatePermissions };
|
package/dist/connect/index.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ declare const HOST_READY_TIMEOUT = 30000;
|
|
|
34
34
|
* JSON-RPC-like message types for wallet ↔ dApp communication.
|
|
35
35
|
*/
|
|
36
36
|
declare const SPHERE_CONNECT_NAMESPACE = "sphere-connect";
|
|
37
|
-
declare const SPHERE_CONNECT_VERSION = "2.
|
|
37
|
+
declare const SPHERE_CONNECT_VERSION = "2.3";
|
|
38
38
|
declare const RPC_METHODS: {
|
|
39
39
|
readonly GET_IDENTITY: "sphere_getIdentity";
|
|
40
40
|
readonly GET_BALANCE: "sphere_getBalance";
|
|
@@ -60,6 +60,7 @@ declare const INTENT_ACTIONS: {
|
|
|
60
60
|
readonly SIGN_MESSAGE: "sign_message";
|
|
61
61
|
readonly MINT: "mint";
|
|
62
62
|
readonly SEND_NFT: "send_nft";
|
|
63
|
+
readonly MINT_NFT: "mint_nft";
|
|
63
64
|
};
|
|
64
65
|
type IntentAction = (typeof INTENT_ACTIONS)[keyof typeof INTENT_ACTIONS];
|
|
65
66
|
declare const ERROR_CODES: {
|
|
@@ -272,6 +273,8 @@ declare const PERMISSION_SCOPES: {
|
|
|
272
273
|
readonly MINT_REQUEST: "mint:request";
|
|
273
274
|
/** #777: moving a coinless token (an NFT). Distinct from transfer:request. */
|
|
274
275
|
readonly NFT_TRANSFER: "nft:transfer";
|
|
276
|
+
/** Minting an NFT signs dApp-chosen content as the user; mint:request and nft:transfer do not imply it. */
|
|
277
|
+
readonly NFT_MINT: "nft:mint";
|
|
275
278
|
};
|
|
276
279
|
type PermissionScope = (typeof PERMISSION_SCOPES)[keyof typeof PERMISSION_SCOPES];
|
|
277
280
|
/** All available permission scopes */
|
|
@@ -371,12 +374,14 @@ interface ConnectHostConfig {
|
|
|
371
374
|
/** Called when dApp sends an intent. Wallet opens corresponding UI.
|
|
372
375
|
* `ctx` (added in Connect 2.1) carries the host-side deadline and an AbortSignal:
|
|
373
376
|
* the wallet MUST dismiss its modal on abort, otherwise the host's own deadline
|
|
374
|
-
* manufactures the double-submit it was added to prevent.
|
|
377
|
+
* manufactures the double-submit it was added to prevent.
|
|
378
|
+
* `error.data` reaches the dApp as `ConnectError.data`, unless the host downgrades the code. */
|
|
375
379
|
onIntent: (action: string, params: Record<string, unknown>, session: ConnectSession, ctx?: IntentContext) => Promise<{
|
|
376
380
|
result?: unknown;
|
|
377
381
|
error?: {
|
|
378
382
|
code: number;
|
|
379
383
|
message: string;
|
|
384
|
+
data?: unknown;
|
|
380
385
|
};
|
|
381
386
|
}>;
|
|
382
387
|
/** Called when dApp explicitly disconnects. Wallet can revoke persisted permissions. */
|
|
@@ -510,12 +515,13 @@ declare class ConnectHost {
|
|
|
510
515
|
};
|
|
511
516
|
/** Get current active session */
|
|
512
517
|
getSession(): ConnectSession | null;
|
|
513
|
-
/** Register an auto-approve handler for an intent action (session-scoped). */
|
|
518
|
+
/** Register an auto-approve handler for an intent action (session-scoped). Throws for an intent that always asks the user. */
|
|
514
519
|
setIntentAutoApprove(action: string, handler: (action: string, params: Record<string, unknown>, session: ConnectSession) => Promise<{
|
|
515
520
|
result?: unknown;
|
|
516
521
|
error?: {
|
|
517
522
|
code: number;
|
|
518
523
|
message: string;
|
|
524
|
+
data?: unknown;
|
|
519
525
|
};
|
|
520
526
|
}>): void;
|
|
521
527
|
/** Remove auto-approve for an intent action. */
|
|
@@ -720,4 +726,75 @@ declare class ConnectClient {
|
|
|
720
726
|
private cleanup;
|
|
721
727
|
}
|
|
722
728
|
|
|
723
|
-
|
|
729
|
+
/** An inline file. */
|
|
730
|
+
interface NftMedia {
|
|
731
|
+
readonly kind: 'media';
|
|
732
|
+
readonly media_type: string;
|
|
733
|
+
readonly bytes: Uint8Array;
|
|
734
|
+
}
|
|
735
|
+
/** A hosted file, pinned by the SHA-256 of its bytes (64 hex; decoded lowercase). */
|
|
736
|
+
interface NftLink {
|
|
737
|
+
readonly kind: 'link';
|
|
738
|
+
readonly media_type: string;
|
|
739
|
+
readonly uri: string;
|
|
740
|
+
readonly sha256: string;
|
|
741
|
+
}
|
|
742
|
+
type NftMediaRef = NftMedia | NftLink;
|
|
743
|
+
interface NftAttribute {
|
|
744
|
+
readonly trait_type: string;
|
|
745
|
+
/** Text, or an integer within ±(2^53 − 1). Decimals and larger numbers are text. */
|
|
746
|
+
readonly value: string | number;
|
|
747
|
+
}
|
|
748
|
+
/** ERC-721 field names; an absent optional field is `null`, never `''`. */
|
|
749
|
+
interface NftMetadata {
|
|
750
|
+
readonly kind: 'metadata';
|
|
751
|
+
readonly name: string;
|
|
752
|
+
readonly description: string | null;
|
|
753
|
+
readonly image: NftMediaRef | null;
|
|
754
|
+
readonly animation_url: NftMediaRef | null;
|
|
755
|
+
readonly external_url: string | null;
|
|
756
|
+
readonly attributes: readonly NftAttribute[];
|
|
757
|
+
readonly collection: string | null;
|
|
758
|
+
/** The collection the item claims: 1–64 bytes as even-length hex (decoded lowercase). Never verified here. */
|
|
759
|
+
readonly collection_id: string | null;
|
|
760
|
+
}
|
|
761
|
+
type NftContent = NftMetadata | NftMedia | NftLink;
|
|
762
|
+
|
|
763
|
+
/** An inline file; `bytes` is standard base64 (RFC 4648 §4, with padding). */
|
|
764
|
+
interface WireNftMedia {
|
|
765
|
+
readonly kind: 'media';
|
|
766
|
+
readonly media_type: string;
|
|
767
|
+
readonly bytes: string;
|
|
768
|
+
}
|
|
769
|
+
interface WireNftMetadata {
|
|
770
|
+
readonly kind: 'metadata';
|
|
771
|
+
readonly name: string;
|
|
772
|
+
readonly description: string | null;
|
|
773
|
+
readonly image: WireNftMedia | NftLink | null;
|
|
774
|
+
readonly animation_url: WireNftMedia | NftLink | null;
|
|
775
|
+
readonly external_url: string | null;
|
|
776
|
+
readonly attributes: readonly NftAttribute[];
|
|
777
|
+
readonly collection: string | null;
|
|
778
|
+
/** Hex, passed through unchanged; `encodeNftContent` judges its value. */
|
|
779
|
+
readonly collection_id: string | null;
|
|
780
|
+
}
|
|
781
|
+
type WireNftContent = WireNftMetadata | WireNftMedia | NftLink;
|
|
782
|
+
/** A type alias, not an interface, so a typed value passes as `ConnectClient.intent` params. */
|
|
783
|
+
type MintNftIntentParams = {
|
|
784
|
+
readonly content: WireNftContent;
|
|
785
|
+
/** Default `true`: the wallet wraps the payload in NftSigned with its chain key as creator. */
|
|
786
|
+
readonly sign?: boolean;
|
|
787
|
+
};
|
|
788
|
+
interface MintNftIntentResult {
|
|
789
|
+
/** 64 lowercase hex. */
|
|
790
|
+
readonly tokenId: string;
|
|
791
|
+
}
|
|
792
|
+
/** `NftContent` → its JSON wire form. Inline bytes become base64; every other field is copied unchanged. */
|
|
793
|
+
declare function nftContentToWire(content: NftContent): WireNftContent;
|
|
794
|
+
/**
|
|
795
|
+
* The wire form → `NftContent`. Checks shape and base64 only, throwing a `SphereError`
|
|
796
|
+
* (`VALIDATION_ERROR`) whose message names the offending field.
|
|
797
|
+
*/
|
|
798
|
+
declare function nftContentFromWire(wire: unknown): NftContent;
|
|
799
|
+
|
|
800
|
+
export { ALL_PERMISSIONS, AUTO_PUSHED_EVENTS, ConnectClient, type ConnectClientConfig, ConnectError, type ConnectEventHandler, ConnectHost, type ConnectHostConfig, type ConnectResult, type ConnectSession, type ConnectTransport, type DAppMetadata, DEFAULT_PERMISSIONS, ERROR_CODES, type ErrorCode, HOST_READY_TIMEOUT, HOST_READY_TYPE, INTENT_ACTIONS, INTENT_PERMISSIONS, type IntentAction, type IntentContext, type LockedRequestContext, METHOD_PERMISSIONS, type MintNftIntentParams, type MintNftIntentResult, type NetworkInfo, type NftAttribute, type NftContent, type NftLink, type NftMedia, type NftMediaRef, type NftMetadata, PERMISSION_SCOPES, type PermissionScope, type PublicIdentity, RPC_METHODS, type RpcMethod, SPHERE_CONNECT_NAMESPACE, SPHERE_CONNECT_VERSION, SPHERE_NETWORKS, type SphereConnectMessage, type SphereEventMessage, type SphereHandshake, type SphereIntentRequest, type SphereIntentResult, type SphereRpcError, type SphereRpcRequest, type SphereRpcResponse, WALLET_EVENTS, type WalletDisconnectedPayload, type WalletEvent, type WalletIdentityChangedPayload, type WalletLockedData, type WalletLockedPayload, type WalletState, type WalletUnlockedPayload, type WireNftContent, type WireNftMedia, type WireNftMetadata, createRequestId, hasIntentPermission, hasMethodPermission, isAutoPushedEvent, isSphereConnectMessage, nftContentFromWire, nftContentToWire, validatePermissions };
|
package/dist/connect/index.js
CHANGED
|
@@ -242,7 +242,7 @@ var HOST_READY_TIMEOUT = 3e4;
|
|
|
242
242
|
|
|
243
243
|
// connect/protocol.ts
|
|
244
244
|
var SPHERE_CONNECT_NAMESPACE = "sphere-connect";
|
|
245
|
-
var SPHERE_CONNECT_VERSION = "2.
|
|
245
|
+
var SPHERE_CONNECT_VERSION = "2.3";
|
|
246
246
|
var DEFAULT_MIN_CLIENT_SDK_VERSION = "0.14.1-0";
|
|
247
247
|
var RPC_METHODS = {
|
|
248
248
|
GET_IDENTITY: "sphere_getIdentity",
|
|
@@ -269,7 +269,9 @@ var INTENT_ACTIONS = {
|
|
|
269
269
|
MINT: "mint",
|
|
270
270
|
// #777: params { to, tokenId, memo? }. Named NFT rather than 'send_token':
|
|
271
271
|
// coins are tokens too, so 'token' does not say which kind moves.
|
|
272
|
-
SEND_NFT: "send_nft"
|
|
272
|
+
SEND_NFT: "send_nft",
|
|
273
|
+
// Connect 2.3: params MintNftIntentParams, result MintNftIntentResult (connect/nft-wire.ts).
|
|
274
|
+
MINT_NFT: "mint_nft"
|
|
273
275
|
};
|
|
274
276
|
var ERROR_CODES = {
|
|
275
277
|
// Standard JSON-RPC
|
|
@@ -403,7 +405,7 @@ function checkCompatibility(input) {
|
|
|
403
405
|
}
|
|
404
406
|
|
|
405
407
|
// connect/version.ts
|
|
406
|
-
var SDK_VERSION = "0.17.2-dev.
|
|
408
|
+
var SDK_VERSION = "0.17.2-dev.3";
|
|
407
409
|
|
|
408
410
|
// connect/permissions.ts
|
|
409
411
|
var PERMISSION_SCOPES = {
|
|
@@ -421,7 +423,9 @@ var PERMISSION_SCOPES = {
|
|
|
421
423
|
SIGN_REQUEST: "sign:request",
|
|
422
424
|
MINT_REQUEST: "mint:request",
|
|
423
425
|
/** #777: moving a coinless token (an NFT). Distinct from transfer:request. */
|
|
424
|
-
NFT_TRANSFER: "nft:transfer"
|
|
426
|
+
NFT_TRANSFER: "nft:transfer",
|
|
427
|
+
/** Minting an NFT signs dApp-chosen content as the user; mint:request and nft:transfer do not imply it. */
|
|
428
|
+
NFT_MINT: "nft:mint"
|
|
425
429
|
};
|
|
426
430
|
var ALL_PERMISSIONS = Object.values(PERMISSION_SCOPES);
|
|
427
431
|
var DEFAULT_PERMISSIONS = [
|
|
@@ -449,7 +453,8 @@ var INTENT_PERMISSIONS = {
|
|
|
449
453
|
[INTENT_ACTIONS.RECEIVE]: PERMISSION_SCOPES.IDENTITY_READ,
|
|
450
454
|
[INTENT_ACTIONS.SIGN_MESSAGE]: PERMISSION_SCOPES.SIGN_REQUEST,
|
|
451
455
|
[INTENT_ACTIONS.MINT]: PERMISSION_SCOPES.MINT_REQUEST,
|
|
452
|
-
[INTENT_ACTIONS.SEND_NFT]: PERMISSION_SCOPES.NFT_TRANSFER
|
|
456
|
+
[INTENT_ACTIONS.SEND_NFT]: PERMISSION_SCOPES.NFT_TRANSFER,
|
|
457
|
+
[INTENT_ACTIONS.MINT_NFT]: PERMISSION_SCOPES.NFT_MINT
|
|
453
458
|
};
|
|
454
459
|
function hasMethodPermission(granted, method) {
|
|
455
460
|
const required = METHOD_PERMISSIONS[method];
|
|
@@ -729,6 +734,7 @@ var CHANNEL_ONLY_CODES = /* @__PURE__ */ new Set([
|
|
|
729
734
|
ERROR_CODES.WALLET_LOCKED,
|
|
730
735
|
ERROR_CODES.NOT_CONNECTED
|
|
731
736
|
]);
|
|
737
|
+
var ALWAYS_ASK_INTENTS = /* @__PURE__ */ new Set([INTENT_ACTIONS.MINT_NFT]);
|
|
732
738
|
var DEFAULT_REQUEST_DEADLINE_MS = 25e3;
|
|
733
739
|
var DEFAULT_INTENT_DEADLINE_MS = 18e4;
|
|
734
740
|
var DEFAULT_HANDSHAKE_DEADLINE_MS = 12e4;
|
|
@@ -814,8 +820,11 @@ var ConnectHost = class {
|
|
|
814
820
|
getSession() {
|
|
815
821
|
return this.session;
|
|
816
822
|
}
|
|
817
|
-
/** Register an auto-approve handler for an intent action (session-scoped). */
|
|
823
|
+
/** Register an auto-approve handler for an intent action (session-scoped). Throws for an intent that always asks the user. */
|
|
818
824
|
setIntentAutoApprove(action, handler) {
|
|
825
|
+
if (ALWAYS_ASK_INTENTS.has(action)) {
|
|
826
|
+
throw new SphereError(`Intent ${action} always asks the user and cannot be auto-approved`, "INVALID_CONFIG");
|
|
827
|
+
}
|
|
819
828
|
this.autoApprovedIntents.set(action, handler);
|
|
820
829
|
}
|
|
821
830
|
/** Remove auto-approve for an intent action. */
|
|
@@ -1304,7 +1313,7 @@ var ConnectHost = class {
|
|
|
1304
1313
|
signal: entry.controller.signal
|
|
1305
1314
|
};
|
|
1306
1315
|
try {
|
|
1307
|
-
const autoHandler = this.autoApprovedIntents.get(msg.action);
|
|
1316
|
+
const autoHandler = ALWAYS_ASK_INTENTS.has(msg.action) ? void 0 : this.autoApprovedIntents.get(msg.action);
|
|
1308
1317
|
const response = autoHandler ? await autoHandler(msg.action, msg.params, session) : await this.config.onIntent(msg.action, msg.params, session, ctx);
|
|
1309
1318
|
if (!this.inFlight.settle(msg.id)) return;
|
|
1310
1319
|
if (response.error) {
|
|
@@ -1318,7 +1327,8 @@ var ConnectHost = class {
|
|
|
1318
1327
|
this.sendIntentError(
|
|
1319
1328
|
msg.id,
|
|
1320
1329
|
asserts ? ERROR_CODES.INTENT_OUTCOME_UNKNOWN : response.error.code,
|
|
1321
|
-
asserts ? INTENT_UNKNOWN_MESSAGE : response.error.message
|
|
1330
|
+
asserts ? INTENT_UNKNOWN_MESSAGE : response.error.message,
|
|
1331
|
+
asserts ? void 0 : response.error.data
|
|
1322
1332
|
);
|
|
1323
1333
|
} else {
|
|
1324
1334
|
this.sendIntentResult(msg.id, response.result);
|
|
@@ -2001,6 +2011,188 @@ var ConnectClient = class {
|
|
|
2001
2011
|
this.locked = false;
|
|
2002
2012
|
}
|
|
2003
2013
|
};
|
|
2014
|
+
|
|
2015
|
+
// core/base64.ts
|
|
2016
|
+
var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
2017
|
+
var INVALID = 255;
|
|
2018
|
+
var SEXTETS = new Uint8Array(128).fill(INVALID);
|
|
2019
|
+
for (let i = 0; i < ALPHABET.length; i++) SEXTETS[ALPHABET.charCodeAt(i)] = i;
|
|
2020
|
+
function base64Encode(bytes) {
|
|
2021
|
+
let out = "";
|
|
2022
|
+
for (let i = 0; i < bytes.length; i += 3) {
|
|
2023
|
+
const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;
|
|
2024
|
+
const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;
|
|
2025
|
+
const triple = bytes[i] << 16 | b1 << 8 | b2;
|
|
2026
|
+
out += ALPHABET[triple >> 18] + ALPHABET[triple >> 12 & 63];
|
|
2027
|
+
out += i + 1 < bytes.length ? ALPHABET[triple >> 6 & 63] : "=";
|
|
2028
|
+
out += i + 2 < bytes.length ? ALPHABET[triple & 63] : "=";
|
|
2029
|
+
}
|
|
2030
|
+
return out;
|
|
2031
|
+
}
|
|
2032
|
+
function base64DecodeCanonical(text) {
|
|
2033
|
+
if (text.length % 4 !== 0) return null;
|
|
2034
|
+
const padding = text.endsWith("==") ? 2 : text.endsWith("=") ? 1 : 0;
|
|
2035
|
+
const out = new Uint8Array(text.length / 4 * 3 - padding);
|
|
2036
|
+
let buffer = 0;
|
|
2037
|
+
let bits = 0;
|
|
2038
|
+
let offset = 0;
|
|
2039
|
+
for (let i = 0; i < text.length - padding; i++) {
|
|
2040
|
+
const code = text.charCodeAt(i);
|
|
2041
|
+
const sextet = code < SEXTETS.length ? SEXTETS[code] : INVALID;
|
|
2042
|
+
if (sextet === INVALID) return null;
|
|
2043
|
+
buffer = (buffer << 6 | sextet) & 4095;
|
|
2044
|
+
bits += 6;
|
|
2045
|
+
if (bits >= 8) {
|
|
2046
|
+
bits -= 8;
|
|
2047
|
+
out[offset++] = buffer >> bits;
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
return (buffer & (1 << bits) - 1) === 0 ? out : null;
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2053
|
+
// connect/nft-wire.ts
|
|
2054
|
+
var METADATA_FIELDS = [
|
|
2055
|
+
"kind",
|
|
2056
|
+
"name",
|
|
2057
|
+
"description",
|
|
2058
|
+
"image",
|
|
2059
|
+
"animation_url",
|
|
2060
|
+
"external_url",
|
|
2061
|
+
"attributes",
|
|
2062
|
+
"collection",
|
|
2063
|
+
"collection_id"
|
|
2064
|
+
];
|
|
2065
|
+
var MEDIA_FIELDS = ["kind", "media_type", "bytes"];
|
|
2066
|
+
var LINK_FIELDS = ["kind", "media_type", "uri", "sha256"];
|
|
2067
|
+
var ATTRIBUTE_FIELDS = ["trait_type", "value"];
|
|
2068
|
+
var CONTENT_KINDS = "must be 'metadata', 'media' or 'link'";
|
|
2069
|
+
var MEDIA_REF_KINDS = "must be 'media' or 'link'";
|
|
2070
|
+
function refuse(field, rule) {
|
|
2071
|
+
return new SphereError(`Invalid NFT ${field}: ${rule}`, "VALIDATION_ERROR");
|
|
2072
|
+
}
|
|
2073
|
+
function mediaToWire(media, field) {
|
|
2074
|
+
if (!(media.bytes instanceof Uint8Array)) throw refuse(`${field}.bytes`, "must be a Uint8Array");
|
|
2075
|
+
return { kind: "media", media_type: media.media_type, bytes: base64Encode(media.bytes) };
|
|
2076
|
+
}
|
|
2077
|
+
function linkToWire(link) {
|
|
2078
|
+
return { kind: "link", media_type: link.media_type, uri: link.uri, sha256: link.sha256 };
|
|
2079
|
+
}
|
|
2080
|
+
function mediaRefToWire(ref, field) {
|
|
2081
|
+
if (ref === null) return null;
|
|
2082
|
+
if (ref?.kind === "media") return mediaToWire(ref, field);
|
|
2083
|
+
if (ref?.kind === "link") return linkToWire(ref);
|
|
2084
|
+
throw refuse(`${field}.kind`, MEDIA_REF_KINDS);
|
|
2085
|
+
}
|
|
2086
|
+
function metadataToWire(metadata) {
|
|
2087
|
+
return {
|
|
2088
|
+
kind: "metadata",
|
|
2089
|
+
name: metadata.name,
|
|
2090
|
+
description: metadata.description,
|
|
2091
|
+
image: mediaRefToWire(metadata.image, "content.image"),
|
|
2092
|
+
animation_url: mediaRefToWire(metadata.animation_url, "content.animation_url"),
|
|
2093
|
+
external_url: metadata.external_url,
|
|
2094
|
+
attributes: metadata.attributes.map(({ trait_type, value }) => ({ trait_type, value })),
|
|
2095
|
+
collection: metadata.collection,
|
|
2096
|
+
collection_id: metadata.collection_id
|
|
2097
|
+
};
|
|
2098
|
+
}
|
|
2099
|
+
function nftContentToWire(content) {
|
|
2100
|
+
switch (content?.kind) {
|
|
2101
|
+
case "metadata":
|
|
2102
|
+
return metadataToWire(content);
|
|
2103
|
+
case "media":
|
|
2104
|
+
return mediaToWire(content, "content");
|
|
2105
|
+
case "link":
|
|
2106
|
+
return linkToWire(content);
|
|
2107
|
+
default:
|
|
2108
|
+
throw refuse("content.kind", CONTENT_KINDS);
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
function recordAt(value, field, rule = "must be an object") {
|
|
2112
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw refuse(field, rule);
|
|
2113
|
+
return value;
|
|
2114
|
+
}
|
|
2115
|
+
function requireExactFields(record, field, fields) {
|
|
2116
|
+
const missing = fields.find((name) => !Object.prototype.hasOwnProperty.call(record, name));
|
|
2117
|
+
if (missing !== void 0) throw refuse(`${field}.${missing}`, "is missing \u2014 an absent optional field is null");
|
|
2118
|
+
const extra = Object.keys(record).find((name) => !fields.includes(name));
|
|
2119
|
+
if (extra !== void 0) throw refuse(`${field}.${extra}`, "is not a field of this item");
|
|
2120
|
+
}
|
|
2121
|
+
function stringAt(record, field, name) {
|
|
2122
|
+
const value = record[name];
|
|
2123
|
+
if (typeof value !== "string") throw refuse(`${field}.${name}`, "must be a string");
|
|
2124
|
+
return value;
|
|
2125
|
+
}
|
|
2126
|
+
function optionalStringAt(record, field, name) {
|
|
2127
|
+
const value = record[name];
|
|
2128
|
+
if (value === null) return null;
|
|
2129
|
+
if (typeof value !== "string") throw refuse(`${field}.${name}`, "must be a string or null");
|
|
2130
|
+
return value;
|
|
2131
|
+
}
|
|
2132
|
+
function mediaFromWire(record, field) {
|
|
2133
|
+
requireExactFields(record, field, MEDIA_FIELDS);
|
|
2134
|
+
const mediaType = stringAt(record, field, "media_type");
|
|
2135
|
+
const bytes = base64DecodeCanonical(stringAt(record, field, "bytes"));
|
|
2136
|
+
if (bytes === null) throw refuse(`${field}.bytes`, "must be canonical standard base64 with padding (RFC 4648 \xA74)");
|
|
2137
|
+
return { kind: "media", media_type: mediaType, bytes };
|
|
2138
|
+
}
|
|
2139
|
+
function linkFromWire(record, field) {
|
|
2140
|
+
requireExactFields(record, field, LINK_FIELDS);
|
|
2141
|
+
return {
|
|
2142
|
+
kind: "link",
|
|
2143
|
+
media_type: stringAt(record, field, "media_type"),
|
|
2144
|
+
uri: stringAt(record, field, "uri"),
|
|
2145
|
+
sha256: stringAt(record, field, "sha256")
|
|
2146
|
+
};
|
|
2147
|
+
}
|
|
2148
|
+
function mediaRefFromWire(value, field) {
|
|
2149
|
+
if (value === null) return null;
|
|
2150
|
+
const record = recordAt(value, field, "must be a media or link object, or null");
|
|
2151
|
+
if (record.kind === "media") return mediaFromWire(record, field);
|
|
2152
|
+
if (record.kind === "link") return linkFromWire(record, field);
|
|
2153
|
+
throw refuse(`${field}.kind`, MEDIA_REF_KINDS);
|
|
2154
|
+
}
|
|
2155
|
+
function attributeFromWire(value, field) {
|
|
2156
|
+
const record = recordAt(value, field);
|
|
2157
|
+
requireExactFields(record, field, ATTRIBUTE_FIELDS);
|
|
2158
|
+
const traitType = stringAt(record, field, "trait_type");
|
|
2159
|
+
const attributeValue = record.value;
|
|
2160
|
+
if (typeof attributeValue !== "string" && typeof attributeValue !== "number") {
|
|
2161
|
+
throw refuse(`${field}.value`, "must be a string or a number");
|
|
2162
|
+
}
|
|
2163
|
+
return { trait_type: traitType, value: attributeValue };
|
|
2164
|
+
}
|
|
2165
|
+
function attributesFromWire(value, field) {
|
|
2166
|
+
if (!Array.isArray(value)) throw refuse(field, "must be an array \u2014 [] when there are none");
|
|
2167
|
+
return Array.from(value, (entry, index) => attributeFromWire(entry, `${field}[${index}]`));
|
|
2168
|
+
}
|
|
2169
|
+
function metadataFromWire(record) {
|
|
2170
|
+
requireExactFields(record, "content", METADATA_FIELDS);
|
|
2171
|
+
return {
|
|
2172
|
+
kind: "metadata",
|
|
2173
|
+
name: stringAt(record, "content", "name"),
|
|
2174
|
+
description: optionalStringAt(record, "content", "description"),
|
|
2175
|
+
image: mediaRefFromWire(record.image, "content.image"),
|
|
2176
|
+
animation_url: mediaRefFromWire(record.animation_url, "content.animation_url"),
|
|
2177
|
+
external_url: optionalStringAt(record, "content", "external_url"),
|
|
2178
|
+
attributes: attributesFromWire(record.attributes, "content.attributes"),
|
|
2179
|
+
collection: optionalStringAt(record, "content", "collection"),
|
|
2180
|
+
collection_id: optionalStringAt(record, "content", "collection_id")
|
|
2181
|
+
};
|
|
2182
|
+
}
|
|
2183
|
+
function nftContentFromWire(wire) {
|
|
2184
|
+
const record = recordAt(wire, "content");
|
|
2185
|
+
switch (record.kind) {
|
|
2186
|
+
case "metadata":
|
|
2187
|
+
return metadataFromWire(record);
|
|
2188
|
+
case "media":
|
|
2189
|
+
return mediaFromWire(record, "content");
|
|
2190
|
+
case "link":
|
|
2191
|
+
return linkFromWire(record, "content");
|
|
2192
|
+
default:
|
|
2193
|
+
throw refuse("content.kind", CONTENT_KINDS);
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2004
2196
|
export {
|
|
2005
2197
|
ALL_PERMISSIONS,
|
|
2006
2198
|
AUTO_PUSHED_EVENTS,
|
|
@@ -2025,6 +2217,8 @@ export {
|
|
|
2025
2217
|
hasMethodPermission,
|
|
2026
2218
|
isAutoPushedEvent,
|
|
2027
2219
|
isSphereConnectMessage,
|
|
2220
|
+
nftContentFromWire,
|
|
2221
|
+
nftContentToWire,
|
|
2028
2222
|
validatePermissions
|
|
2029
2223
|
};
|
|
2030
2224
|
//# sourceMappingURL=index.js.map
|