@partylayer/adapter-nightly 0.2.10 → 0.2.11
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/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -67,6 +67,9 @@ var NightlyAdapter = class {
|
|
|
67
67
|
partyId,
|
|
68
68
|
session: {
|
|
69
69
|
walletId: this.walletId,
|
|
70
|
+
// The Nightly provider does not report the connected network → not
|
|
71
|
+
// wallet-reported, so network-mismatch detection is limited for this
|
|
72
|
+
// adapter (echoes the requested ctx.network).
|
|
70
73
|
network: ctx.network,
|
|
71
74
|
createdAt: Date.now(),
|
|
72
75
|
metadata: {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/nightly-adapter.ts"],"names":["toWalletId","WalletNotInstalledError","toPartyId","mapUnknownErrorToPartyLayerError","toSignature","CapabilityNotSupportedError","toTransactionHash"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Nightly Wallet adapter implementation\n *\n * Nightly is a multichain wallet with Canton Network support.\n * The wallet injects at window.nightly.canton and uses a custom\n * (non-CIP-0103) interface with callback-based signing.\n *\n * Reference: https://docs.nightly.app/docs/canton/canton/connect/\n * Template: https://github.com/nightly-labs/canton-web3-template\n */\n\nimport type {\n WalletAdapter,\n AdapterContext,\n AdapterDetectResult,\n AdapterConnectResult,\n SignMessageParams,\n SignTransactionParams,\n SubmitTransactionParams,\n SignedMessage,\n SignedTransaction,\n TxReceipt,\n LedgerApiParams,\n LedgerApiResult,\n Session,\n PersistedSession,\n CapabilityKey,\n PartyId,\n} from '@partylayer/core';\nimport {\n toWalletId,\n toPartyId,\n toTransactionHash,\n toSignature,\n WalletNotInstalledError,\n CapabilityNotSupportedError,\n mapUnknownErrorToPartyLayerError,\n} from '@partylayer/core';\n\n// ─── Nightly Canton Types ───────────────────────────────────────────────────\n\n/** Sign request response types from Nightly wallet */\nenum SignRequestResponseType {\n SIGN_REQUEST_APPROVED = 'sign_request_approved',\n SIGN_REQUEST_REJECTED = 'sign_request_rejected',\n SIGN_REQUEST_ERROR = 'sign_request_error',\n}\n\ninterface SignRequestResponse {\n type: SignRequestResponseType;\n data:\n | { signature?: string; updateId?: string }\n | { reason: string }\n | { error: string };\n}\n\ninterface Instrument {\n id: string;\n admin: string;\n}\n\ninterface TransactionCommand {\n command: unknown;\n disclosedContracts: unknown[];\n}\n\ninterface CreateTransferCommandParams {\n receiverPartyId: string;\n amount: string;\n instrument: Instrument;\n memo?: string;\n expiryDate?: string;\n}\n\n/** The wallet object returned after successful connection */\ninterface NightlyCantonWallet {\n partyId: string;\n publicKey: string;\n signMessage: (\n message: string,\n onResponse: (response: SignRequestResponse) => void,\n ) => void;\n createTransferCommand: (\n params: CreateTransferCommandParams,\n ) => Promise<TransactionCommand>;\n submitTransactionCommand: (\n transactionCommand: TransactionCommand,\n onResponse: (response: SignRequestResponse) => void,\n ) => void;\n getPendingTransactions: () => Promise<unknown[] | null>;\n getHoldingUtxos: () => Promise<unknown[] | null>;\n}\n\n/** The injected provider at window.nightly.canton */\ninterface NightlyCantonProvider extends NightlyCantonWallet {\n connect: () => Promise<{ partyId: string; publicKey: string }>;\n disconnect: () => Promise<void>;\n isConnected: () => boolean;\n}\n\ndeclare global {\n interface Window {\n nightly?: {\n canton?: NightlyCantonProvider;\n };\n }\n}\n\n// ─── Adapter ────────────────────────────────────────────────────────────────\n\n/**\n * Nightly Wallet adapter\n *\n * Implements WalletAdapter interface for Nightly Wallet's Canton support.\n * The wallet injects at window.nightly.canton and provides:\n * - connect/disconnect via Promise\n * - signMessage via callback\n * - transaction commands via callback\n * - session restore via isConnected()\n */\nexport class NightlyAdapter implements WalletAdapter {\n readonly walletId = toWalletId('nightly');\n readonly name = 'Nightly';\n\n private wallet: NightlyCantonWallet | null = null;\n\n getCapabilities(): CapabilityKey[] {\n return [\n 'connect',\n 'disconnect',\n 'restore',\n 'signMessage',\n 'submitTransaction',\n 'ledgerApi',\n 'events',\n 'injected',\n ];\n }\n\n /**\n * Detect if Nightly wallet extension is installed.\n * Checks for window.nightly.canton provider.\n */\n async detectInstalled(): Promise<AdapterDetectResult> {\n if (typeof window === 'undefined') {\n return { installed: false, reason: 'Browser environment required' };\n }\n\n if (window.nightly?.canton) {\n return {\n installed: true,\n reason: 'Nightly wallet detected',\n };\n }\n\n return {\n installed: false,\n reason:\n 'Nightly wallet not detected. Install from https://nightly.app/download',\n };\n }\n\n /**\n * Connect to Nightly Wallet.\n *\n * Calls window.nightly.canton.connect() which opens the extension\n * popup for user approval.\n */\n async connect(\n ctx: AdapterContext,\n _opts?: { timeoutMs?: number; partyId?: PartyId },\n ): Promise<AdapterConnectResult> {\n try {\n const provider = window.nightly?.canton;\n if (!provider) {\n throw new WalletNotInstalledError(\n this.walletId,\n 'Nightly wallet not detected. Install from https://nightly.app/download',\n );\n }\n\n ctx.logger.debug('Connecting to Nightly Wallet', {\n appName: ctx.appName,\n network: ctx.network,\n });\n\n // connect() opens the extension popup for approval\n await provider.connect();\n\n // After connect, the provider itself acts as the wallet\n this.wallet = provider;\n const partyId = toPartyId(provider.partyId);\n\n ctx.logger.info('Connected to Nightly Wallet', {\n partyId: provider.partyId,\n });\n\n return {\n partyId,\n session: {\n walletId: this.walletId,\n network: ctx.network,\n createdAt: Date.now(),\n metadata: {\n publicKey: provider.publicKey,\n },\n },\n capabilities: this.getCapabilities(),\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'connect',\n transport: 'injected',\n details: { origin: ctx.origin, network: ctx.network },\n });\n }\n }\n\n /**\n * Disconnect from Nightly Wallet.\n */\n async disconnect(ctx: AdapterContext, _session: Session): Promise<void> {\n try {\n await window.nightly?.canton?.disconnect();\n } catch (err) {\n ctx.logger.warn('Error during Nightly wallet disconnect', err);\n }\n this.wallet = null;\n }\n\n /**\n * Restore session — check if Nightly is still connected.\n */\n async restore(\n ctx: AdapterContext,\n persisted: PersistedSession,\n ): Promise<Session | null> {\n try {\n if (typeof window === 'undefined') return null;\n\n if (persisted.expiresAt && Date.now() >= persisted.expiresAt) {\n return null;\n }\n\n const provider = window.nightly?.canton;\n if (!provider) return null;\n\n // Check if the wallet reports being connected\n if (typeof provider.isConnected === 'function' && provider.isConnected()) {\n this.wallet = provider;\n ctx.logger.debug('Restored Nightly Wallet session', {\n partyId: provider.partyId,\n });\n return { ...persisted, walletId: this.walletId };\n }\n\n return null;\n } catch (err) {\n ctx.logger.warn('Failed to restore Nightly wallet session', err);\n return null;\n }\n }\n\n /**\n * Sign a message.\n *\n * Nightly uses a callback-based signMessage API — we wrap it\n * in a Promise for the WalletAdapter interface.\n */\n async signMessage(\n ctx: AdapterContext,\n session: Session,\n params: SignMessageParams,\n ): Promise<SignedMessage> {\n try {\n if (!this.wallet) {\n throw new Error('Not connected to Nightly Wallet');\n }\n\n ctx.logger.debug('Signing message with Nightly Wallet', {\n sessionId: session.sessionId,\n messageLength: params.message.length,\n });\n\n const signature = await new Promise<string>((resolve, reject) => {\n this.wallet!.signMessage(params.message, (response) => {\n if (response.type === SignRequestResponseType.SIGN_REQUEST_APPROVED) {\n const data = response.data as { signature?: string };\n resolve(data.signature || '');\n } else if (\n response.type === SignRequestResponseType.SIGN_REQUEST_REJECTED\n ) {\n const data = response.data as { reason: string };\n reject(new Error(`Sign rejected: ${data.reason}`));\n } else {\n const data = response.data as { error: string };\n reject(new Error(`Sign error: ${data.error}`));\n }\n });\n });\n\n return {\n signature: toSignature(signature),\n partyId: session.partyId,\n message: params.message,\n nonce: params.nonce,\n domain: params.domain,\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'signMessage',\n transport: 'injected',\n details: { sessionId: session.sessionId },\n });\n }\n }\n\n /**\n * Sign a transaction — not supported standalone.\n *\n * Nightly combines signing and submission via submitTransactionCommand.\n */\n async signTransaction(\n _ctx: AdapterContext,\n _session: Session,\n _params: SignTransactionParams,\n ): Promise<SignedTransaction> {\n throw new CapabilityNotSupportedError(\n this.walletId,\n 'signTransaction — Nightly combines signing and submission. Use submitTransaction instead.',\n );\n }\n\n /**\n * Submit a transaction.\n *\n * Nightly uses callback-based submitTransactionCommand.\n * The signedTx should be a TransactionCommand object created via\n * createTransferCommand or createTransactionChoiceCommand.\n */\n async submitTransaction(\n ctx: AdapterContext,\n session: Session,\n params: SubmitTransactionParams,\n ): Promise<TxReceipt> {\n try {\n if (!this.wallet) {\n throw new Error('Not connected to Nightly Wallet');\n }\n\n ctx.logger.debug('Submitting transaction with Nightly Wallet', {\n sessionId: session.sessionId,\n });\n\n const txCommand = params.signedTx as TransactionCommand;\n\n const result = await new Promise<{ signature?: string; updateId?: string }>(\n (resolve, reject) => {\n this.wallet!.submitTransactionCommand(txCommand, (response) => {\n if (\n response.type === SignRequestResponseType.SIGN_REQUEST_APPROVED\n ) {\n resolve(\n response.data as { signature?: string; updateId?: string },\n );\n } else if (\n response.type === SignRequestResponseType.SIGN_REQUEST_REJECTED\n ) {\n const data = response.data as { reason: string };\n reject(new Error(`Transaction rejected: ${data.reason}`));\n } else {\n const data = response.data as { error: string };\n reject(new Error(`Transaction error: ${data.error}`));\n }\n });\n },\n );\n\n const hash =\n result.updateId ||\n result.signature ||\n `tx_${Date.now()}_${Math.random().toString(36).substring(2, 10)}`;\n\n return {\n transactionHash: toTransactionHash(hash),\n submittedAt: Date.now(),\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'submitTransaction',\n transport: 'injected',\n details: { sessionId: session.sessionId },\n });\n }\n }\n\n /**\n * Proxy a Ledger API request through the Nightly Wallet.\n *\n * Nightly's canton provider may expose ledgerApi or a generic request()\n * method. We check at runtime — the interface is cast to include these\n * optional methods that may be present in newer wallet versions.\n */\n async ledgerApi(\n ctx: AdapterContext,\n session: Session,\n params: LedgerApiParams,\n ): Promise<LedgerApiResult> {\n try {\n const provider = window.nightly?.canton as unknown as\n | (NightlyCantonProvider & {\n ledgerApi?: (p: { requestMethod: string; resource: string; body?: string }) => Promise<unknown>;\n request?: (args: { method: string; params?: unknown }) => Promise<unknown>;\n })\n | undefined;\n\n if (!provider) {\n throw new Error('Not connected to Nightly Wallet');\n }\n\n ctx.logger.debug('Proxying ledger API request via Nightly Wallet', {\n sessionId: session.sessionId,\n requestMethod: params.requestMethod,\n resource: params.resource,\n });\n\n if (typeof provider.ledgerApi === 'function') {\n const result = await provider.ledgerApi({\n requestMethod: params.requestMethod,\n resource: params.resource,\n body: params.body,\n });\n const response = result as { response?: string } | string;\n return {\n response: typeof response === 'string'\n ? response\n : (response?.response ?? JSON.stringify(response)),\n };\n }\n\n if (typeof provider.request === 'function') {\n const result = await provider.request({\n method: 'ledgerApi',\n params: {\n requestMethod: params.requestMethod,\n resource: params.resource,\n body: params.body,\n },\n });\n const response = result as { response?: string } | string;\n return {\n response: typeof response === 'string'\n ? response\n : (response?.response ?? JSON.stringify(response)),\n };\n }\n\n throw new CapabilityNotSupportedError(\n this.walletId,\n 'ledgerApi — update Nightly Wallet to a version that supports CIP-0103 ledgerApi',\n );\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'ledgerApi',\n transport: 'injected',\n details: { sessionId: session.sessionId },\n });\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/nightly-adapter.ts"],"names":["toWalletId","WalletNotInstalledError","toPartyId","mapUnknownErrorToPartyLayerError","toSignature","CapabilityNotSupportedError","toTransactionHash"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Nightly Wallet adapter implementation\n *\n * Nightly is a multichain wallet with Canton Network support.\n * The wallet injects at window.nightly.canton and uses a custom\n * (non-CIP-0103) interface with callback-based signing.\n *\n * Reference: https://docs.nightly.app/docs/canton/canton/connect/\n * Template: https://github.com/nightly-labs/canton-web3-template\n */\n\nimport type {\n WalletAdapter,\n AdapterContext,\n AdapterDetectResult,\n AdapterConnectResult,\n SignMessageParams,\n SignTransactionParams,\n SubmitTransactionParams,\n SignedMessage,\n SignedTransaction,\n TxReceipt,\n LedgerApiParams,\n LedgerApiResult,\n Session,\n PersistedSession,\n CapabilityKey,\n PartyId,\n} from '@partylayer/core';\nimport {\n toWalletId,\n toPartyId,\n toTransactionHash,\n toSignature,\n WalletNotInstalledError,\n CapabilityNotSupportedError,\n mapUnknownErrorToPartyLayerError,\n} from '@partylayer/core';\n\n// ─── Nightly Canton Types ───────────────────────────────────────────────────\n\n/** Sign request response types from Nightly wallet */\nenum SignRequestResponseType {\n SIGN_REQUEST_APPROVED = 'sign_request_approved',\n SIGN_REQUEST_REJECTED = 'sign_request_rejected',\n SIGN_REQUEST_ERROR = 'sign_request_error',\n}\n\ninterface SignRequestResponse {\n type: SignRequestResponseType;\n data:\n | { signature?: string; updateId?: string }\n | { reason: string }\n | { error: string };\n}\n\ninterface Instrument {\n id: string;\n admin: string;\n}\n\ninterface TransactionCommand {\n command: unknown;\n disclosedContracts: unknown[];\n}\n\ninterface CreateTransferCommandParams {\n receiverPartyId: string;\n amount: string;\n instrument: Instrument;\n memo?: string;\n expiryDate?: string;\n}\n\n/** The wallet object returned after successful connection */\ninterface NightlyCantonWallet {\n partyId: string;\n publicKey: string;\n signMessage: (\n message: string,\n onResponse: (response: SignRequestResponse) => void,\n ) => void;\n createTransferCommand: (\n params: CreateTransferCommandParams,\n ) => Promise<TransactionCommand>;\n submitTransactionCommand: (\n transactionCommand: TransactionCommand,\n onResponse: (response: SignRequestResponse) => void,\n ) => void;\n getPendingTransactions: () => Promise<unknown[] | null>;\n getHoldingUtxos: () => Promise<unknown[] | null>;\n}\n\n/** The injected provider at window.nightly.canton */\ninterface NightlyCantonProvider extends NightlyCantonWallet {\n connect: () => Promise<{ partyId: string; publicKey: string }>;\n disconnect: () => Promise<void>;\n isConnected: () => boolean;\n}\n\ndeclare global {\n interface Window {\n nightly?: {\n canton?: NightlyCantonProvider;\n };\n }\n}\n\n// ─── Adapter ────────────────────────────────────────────────────────────────\n\n/**\n * Nightly Wallet adapter\n *\n * Implements WalletAdapter interface for Nightly Wallet's Canton support.\n * The wallet injects at window.nightly.canton and provides:\n * - connect/disconnect via Promise\n * - signMessage via callback\n * - transaction commands via callback\n * - session restore via isConnected()\n */\nexport class NightlyAdapter implements WalletAdapter {\n readonly walletId = toWalletId('nightly');\n readonly name = 'Nightly';\n\n private wallet: NightlyCantonWallet | null = null;\n\n getCapabilities(): CapabilityKey[] {\n return [\n 'connect',\n 'disconnect',\n 'restore',\n 'signMessage',\n 'submitTransaction',\n 'ledgerApi',\n 'events',\n 'injected',\n ];\n }\n\n /**\n * Detect if Nightly wallet extension is installed.\n * Checks for window.nightly.canton provider.\n */\n async detectInstalled(): Promise<AdapterDetectResult> {\n if (typeof window === 'undefined') {\n return { installed: false, reason: 'Browser environment required' };\n }\n\n if (window.nightly?.canton) {\n return {\n installed: true,\n reason: 'Nightly wallet detected',\n };\n }\n\n return {\n installed: false,\n reason:\n 'Nightly wallet not detected. Install from https://nightly.app/download',\n };\n }\n\n /**\n * Connect to Nightly Wallet.\n *\n * Calls window.nightly.canton.connect() which opens the extension\n * popup for user approval.\n */\n async connect(\n ctx: AdapterContext,\n _opts?: { timeoutMs?: number; partyId?: PartyId },\n ): Promise<AdapterConnectResult> {\n try {\n const provider = window.nightly?.canton;\n if (!provider) {\n throw new WalletNotInstalledError(\n this.walletId,\n 'Nightly wallet not detected. Install from https://nightly.app/download',\n );\n }\n\n ctx.logger.debug('Connecting to Nightly Wallet', {\n appName: ctx.appName,\n network: ctx.network,\n });\n\n // connect() opens the extension popup for approval\n await provider.connect();\n\n // After connect, the provider itself acts as the wallet\n this.wallet = provider;\n const partyId = toPartyId(provider.partyId);\n\n ctx.logger.info('Connected to Nightly Wallet', {\n partyId: provider.partyId,\n });\n\n return {\n partyId,\n session: {\n walletId: this.walletId,\n // The Nightly provider does not report the connected network → not\n // wallet-reported, so network-mismatch detection is limited for this\n // adapter (echoes the requested ctx.network).\n network: ctx.network,\n createdAt: Date.now(),\n metadata: {\n publicKey: provider.publicKey,\n },\n },\n capabilities: this.getCapabilities(),\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'connect',\n transport: 'injected',\n details: { origin: ctx.origin, network: ctx.network },\n });\n }\n }\n\n /**\n * Disconnect from Nightly Wallet.\n */\n async disconnect(ctx: AdapterContext, _session: Session): Promise<void> {\n try {\n await window.nightly?.canton?.disconnect();\n } catch (err) {\n ctx.logger.warn('Error during Nightly wallet disconnect', err);\n }\n this.wallet = null;\n }\n\n /**\n * Restore session — check if Nightly is still connected.\n */\n async restore(\n ctx: AdapterContext,\n persisted: PersistedSession,\n ): Promise<Session | null> {\n try {\n if (typeof window === 'undefined') return null;\n\n if (persisted.expiresAt && Date.now() >= persisted.expiresAt) {\n return null;\n }\n\n const provider = window.nightly?.canton;\n if (!provider) return null;\n\n // Check if the wallet reports being connected\n if (typeof provider.isConnected === 'function' && provider.isConnected()) {\n this.wallet = provider;\n ctx.logger.debug('Restored Nightly Wallet session', {\n partyId: provider.partyId,\n });\n return { ...persisted, walletId: this.walletId };\n }\n\n return null;\n } catch (err) {\n ctx.logger.warn('Failed to restore Nightly wallet session', err);\n return null;\n }\n }\n\n /**\n * Sign a message.\n *\n * Nightly uses a callback-based signMessage API — we wrap it\n * in a Promise for the WalletAdapter interface.\n */\n async signMessage(\n ctx: AdapterContext,\n session: Session,\n params: SignMessageParams,\n ): Promise<SignedMessage> {\n try {\n if (!this.wallet) {\n throw new Error('Not connected to Nightly Wallet');\n }\n\n ctx.logger.debug('Signing message with Nightly Wallet', {\n sessionId: session.sessionId,\n messageLength: params.message.length,\n });\n\n const signature = await new Promise<string>((resolve, reject) => {\n this.wallet!.signMessage(params.message, (response) => {\n if (response.type === SignRequestResponseType.SIGN_REQUEST_APPROVED) {\n const data = response.data as { signature?: string };\n resolve(data.signature || '');\n } else if (\n response.type === SignRequestResponseType.SIGN_REQUEST_REJECTED\n ) {\n const data = response.data as { reason: string };\n reject(new Error(`Sign rejected: ${data.reason}`));\n } else {\n const data = response.data as { error: string };\n reject(new Error(`Sign error: ${data.error}`));\n }\n });\n });\n\n return {\n signature: toSignature(signature),\n partyId: session.partyId,\n message: params.message,\n nonce: params.nonce,\n domain: params.domain,\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'signMessage',\n transport: 'injected',\n details: { sessionId: session.sessionId },\n });\n }\n }\n\n /**\n * Sign a transaction — not supported standalone.\n *\n * Nightly combines signing and submission via submitTransactionCommand.\n */\n async signTransaction(\n _ctx: AdapterContext,\n _session: Session,\n _params: SignTransactionParams,\n ): Promise<SignedTransaction> {\n throw new CapabilityNotSupportedError(\n this.walletId,\n 'signTransaction — Nightly combines signing and submission. Use submitTransaction instead.',\n );\n }\n\n /**\n * Submit a transaction.\n *\n * Nightly uses callback-based submitTransactionCommand.\n * The signedTx should be a TransactionCommand object created via\n * createTransferCommand or createTransactionChoiceCommand.\n */\n async submitTransaction(\n ctx: AdapterContext,\n session: Session,\n params: SubmitTransactionParams,\n ): Promise<TxReceipt> {\n try {\n if (!this.wallet) {\n throw new Error('Not connected to Nightly Wallet');\n }\n\n ctx.logger.debug('Submitting transaction with Nightly Wallet', {\n sessionId: session.sessionId,\n });\n\n const txCommand = params.signedTx as TransactionCommand;\n\n const result = await new Promise<{ signature?: string; updateId?: string }>(\n (resolve, reject) => {\n this.wallet!.submitTransactionCommand(txCommand, (response) => {\n if (\n response.type === SignRequestResponseType.SIGN_REQUEST_APPROVED\n ) {\n resolve(\n response.data as { signature?: string; updateId?: string },\n );\n } else if (\n response.type === SignRequestResponseType.SIGN_REQUEST_REJECTED\n ) {\n const data = response.data as { reason: string };\n reject(new Error(`Transaction rejected: ${data.reason}`));\n } else {\n const data = response.data as { error: string };\n reject(new Error(`Transaction error: ${data.error}`));\n }\n });\n },\n );\n\n const hash =\n result.updateId ||\n result.signature ||\n `tx_${Date.now()}_${Math.random().toString(36).substring(2, 10)}`;\n\n return {\n transactionHash: toTransactionHash(hash),\n submittedAt: Date.now(),\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'submitTransaction',\n transport: 'injected',\n details: { sessionId: session.sessionId },\n });\n }\n }\n\n /**\n * Proxy a Ledger API request through the Nightly Wallet.\n *\n * Nightly's canton provider may expose ledgerApi or a generic request()\n * method. We check at runtime — the interface is cast to include these\n * optional methods that may be present in newer wallet versions.\n */\n async ledgerApi(\n ctx: AdapterContext,\n session: Session,\n params: LedgerApiParams,\n ): Promise<LedgerApiResult> {\n try {\n const provider = window.nightly?.canton as unknown as\n | (NightlyCantonProvider & {\n ledgerApi?: (p: { requestMethod: string; resource: string; body?: string }) => Promise<unknown>;\n request?: (args: { method: string; params?: unknown }) => Promise<unknown>;\n })\n | undefined;\n\n if (!provider) {\n throw new Error('Not connected to Nightly Wallet');\n }\n\n ctx.logger.debug('Proxying ledger API request via Nightly Wallet', {\n sessionId: session.sessionId,\n requestMethod: params.requestMethod,\n resource: params.resource,\n });\n\n if (typeof provider.ledgerApi === 'function') {\n const result = await provider.ledgerApi({\n requestMethod: params.requestMethod,\n resource: params.resource,\n body: params.body,\n });\n const response = result as { response?: string } | string;\n return {\n response: typeof response === 'string'\n ? response\n : (response?.response ?? JSON.stringify(response)),\n };\n }\n\n if (typeof provider.request === 'function') {\n const result = await provider.request({\n method: 'ledgerApi',\n params: {\n requestMethod: params.requestMethod,\n resource: params.resource,\n body: params.body,\n },\n });\n const response = result as { response?: string } | string;\n return {\n response: typeof response === 'string'\n ? response\n : (response?.response ?? JSON.stringify(response)),\n };\n }\n\n throw new CapabilityNotSupportedError(\n this.walletId,\n 'ledgerApi — update Nightly Wallet to a version that supports CIP-0103 ledgerApi',\n );\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'ledgerApi',\n transport: 'injected',\n details: { sessionId: session.sessionId },\n });\n }\n }\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -65,6 +65,9 @@ var NightlyAdapter = class {
|
|
|
65
65
|
partyId,
|
|
66
66
|
session: {
|
|
67
67
|
walletId: this.walletId,
|
|
68
|
+
// The Nightly provider does not report the connected network → not
|
|
69
|
+
// wallet-reported, so network-mismatch detection is limited for this
|
|
70
|
+
// adapter (echoes the requested ctx.network).
|
|
68
71
|
network: ctx.network,
|
|
69
72
|
createdAt: Date.now(),
|
|
70
73
|
metadata: {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/nightly-adapter.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Nightly Wallet adapter implementation\n *\n * Nightly is a multichain wallet with Canton Network support.\n * The wallet injects at window.nightly.canton and uses a custom\n * (non-CIP-0103) interface with callback-based signing.\n *\n * Reference: https://docs.nightly.app/docs/canton/canton/connect/\n * Template: https://github.com/nightly-labs/canton-web3-template\n */\n\nimport type {\n WalletAdapter,\n AdapterContext,\n AdapterDetectResult,\n AdapterConnectResult,\n SignMessageParams,\n SignTransactionParams,\n SubmitTransactionParams,\n SignedMessage,\n SignedTransaction,\n TxReceipt,\n LedgerApiParams,\n LedgerApiResult,\n Session,\n PersistedSession,\n CapabilityKey,\n PartyId,\n} from '@partylayer/core';\nimport {\n toWalletId,\n toPartyId,\n toTransactionHash,\n toSignature,\n WalletNotInstalledError,\n CapabilityNotSupportedError,\n mapUnknownErrorToPartyLayerError,\n} from '@partylayer/core';\n\n// ─── Nightly Canton Types ───────────────────────────────────────────────────\n\n/** Sign request response types from Nightly wallet */\nenum SignRequestResponseType {\n SIGN_REQUEST_APPROVED = 'sign_request_approved',\n SIGN_REQUEST_REJECTED = 'sign_request_rejected',\n SIGN_REQUEST_ERROR = 'sign_request_error',\n}\n\ninterface SignRequestResponse {\n type: SignRequestResponseType;\n data:\n | { signature?: string; updateId?: string }\n | { reason: string }\n | { error: string };\n}\n\ninterface Instrument {\n id: string;\n admin: string;\n}\n\ninterface TransactionCommand {\n command: unknown;\n disclosedContracts: unknown[];\n}\n\ninterface CreateTransferCommandParams {\n receiverPartyId: string;\n amount: string;\n instrument: Instrument;\n memo?: string;\n expiryDate?: string;\n}\n\n/** The wallet object returned after successful connection */\ninterface NightlyCantonWallet {\n partyId: string;\n publicKey: string;\n signMessage: (\n message: string,\n onResponse: (response: SignRequestResponse) => void,\n ) => void;\n createTransferCommand: (\n params: CreateTransferCommandParams,\n ) => Promise<TransactionCommand>;\n submitTransactionCommand: (\n transactionCommand: TransactionCommand,\n onResponse: (response: SignRequestResponse) => void,\n ) => void;\n getPendingTransactions: () => Promise<unknown[] | null>;\n getHoldingUtxos: () => Promise<unknown[] | null>;\n}\n\n/** The injected provider at window.nightly.canton */\ninterface NightlyCantonProvider extends NightlyCantonWallet {\n connect: () => Promise<{ partyId: string; publicKey: string }>;\n disconnect: () => Promise<void>;\n isConnected: () => boolean;\n}\n\ndeclare global {\n interface Window {\n nightly?: {\n canton?: NightlyCantonProvider;\n };\n }\n}\n\n// ─── Adapter ────────────────────────────────────────────────────────────────\n\n/**\n * Nightly Wallet adapter\n *\n * Implements WalletAdapter interface for Nightly Wallet's Canton support.\n * The wallet injects at window.nightly.canton and provides:\n * - connect/disconnect via Promise\n * - signMessage via callback\n * - transaction commands via callback\n * - session restore via isConnected()\n */\nexport class NightlyAdapter implements WalletAdapter {\n readonly walletId = toWalletId('nightly');\n readonly name = 'Nightly';\n\n private wallet: NightlyCantonWallet | null = null;\n\n getCapabilities(): CapabilityKey[] {\n return [\n 'connect',\n 'disconnect',\n 'restore',\n 'signMessage',\n 'submitTransaction',\n 'ledgerApi',\n 'events',\n 'injected',\n ];\n }\n\n /**\n * Detect if Nightly wallet extension is installed.\n * Checks for window.nightly.canton provider.\n */\n async detectInstalled(): Promise<AdapterDetectResult> {\n if (typeof window === 'undefined') {\n return { installed: false, reason: 'Browser environment required' };\n }\n\n if (window.nightly?.canton) {\n return {\n installed: true,\n reason: 'Nightly wallet detected',\n };\n }\n\n return {\n installed: false,\n reason:\n 'Nightly wallet not detected. Install from https://nightly.app/download',\n };\n }\n\n /**\n * Connect to Nightly Wallet.\n *\n * Calls window.nightly.canton.connect() which opens the extension\n * popup for user approval.\n */\n async connect(\n ctx: AdapterContext,\n _opts?: { timeoutMs?: number; partyId?: PartyId },\n ): Promise<AdapterConnectResult> {\n try {\n const provider = window.nightly?.canton;\n if (!provider) {\n throw new WalletNotInstalledError(\n this.walletId,\n 'Nightly wallet not detected. Install from https://nightly.app/download',\n );\n }\n\n ctx.logger.debug('Connecting to Nightly Wallet', {\n appName: ctx.appName,\n network: ctx.network,\n });\n\n // connect() opens the extension popup for approval\n await provider.connect();\n\n // After connect, the provider itself acts as the wallet\n this.wallet = provider;\n const partyId = toPartyId(provider.partyId);\n\n ctx.logger.info('Connected to Nightly Wallet', {\n partyId: provider.partyId,\n });\n\n return {\n partyId,\n session: {\n walletId: this.walletId,\n network: ctx.network,\n createdAt: Date.now(),\n metadata: {\n publicKey: provider.publicKey,\n },\n },\n capabilities: this.getCapabilities(),\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'connect',\n transport: 'injected',\n details: { origin: ctx.origin, network: ctx.network },\n });\n }\n }\n\n /**\n * Disconnect from Nightly Wallet.\n */\n async disconnect(ctx: AdapterContext, _session: Session): Promise<void> {\n try {\n await window.nightly?.canton?.disconnect();\n } catch (err) {\n ctx.logger.warn('Error during Nightly wallet disconnect', err);\n }\n this.wallet = null;\n }\n\n /**\n * Restore session — check if Nightly is still connected.\n */\n async restore(\n ctx: AdapterContext,\n persisted: PersistedSession,\n ): Promise<Session | null> {\n try {\n if (typeof window === 'undefined') return null;\n\n if (persisted.expiresAt && Date.now() >= persisted.expiresAt) {\n return null;\n }\n\n const provider = window.nightly?.canton;\n if (!provider) return null;\n\n // Check if the wallet reports being connected\n if (typeof provider.isConnected === 'function' && provider.isConnected()) {\n this.wallet = provider;\n ctx.logger.debug('Restored Nightly Wallet session', {\n partyId: provider.partyId,\n });\n return { ...persisted, walletId: this.walletId };\n }\n\n return null;\n } catch (err) {\n ctx.logger.warn('Failed to restore Nightly wallet session', err);\n return null;\n }\n }\n\n /**\n * Sign a message.\n *\n * Nightly uses a callback-based signMessage API — we wrap it\n * in a Promise for the WalletAdapter interface.\n */\n async signMessage(\n ctx: AdapterContext,\n session: Session,\n params: SignMessageParams,\n ): Promise<SignedMessage> {\n try {\n if (!this.wallet) {\n throw new Error('Not connected to Nightly Wallet');\n }\n\n ctx.logger.debug('Signing message with Nightly Wallet', {\n sessionId: session.sessionId,\n messageLength: params.message.length,\n });\n\n const signature = await new Promise<string>((resolve, reject) => {\n this.wallet!.signMessage(params.message, (response) => {\n if (response.type === SignRequestResponseType.SIGN_REQUEST_APPROVED) {\n const data = response.data as { signature?: string };\n resolve(data.signature || '');\n } else if (\n response.type === SignRequestResponseType.SIGN_REQUEST_REJECTED\n ) {\n const data = response.data as { reason: string };\n reject(new Error(`Sign rejected: ${data.reason}`));\n } else {\n const data = response.data as { error: string };\n reject(new Error(`Sign error: ${data.error}`));\n }\n });\n });\n\n return {\n signature: toSignature(signature),\n partyId: session.partyId,\n message: params.message,\n nonce: params.nonce,\n domain: params.domain,\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'signMessage',\n transport: 'injected',\n details: { sessionId: session.sessionId },\n });\n }\n }\n\n /**\n * Sign a transaction — not supported standalone.\n *\n * Nightly combines signing and submission via submitTransactionCommand.\n */\n async signTransaction(\n _ctx: AdapterContext,\n _session: Session,\n _params: SignTransactionParams,\n ): Promise<SignedTransaction> {\n throw new CapabilityNotSupportedError(\n this.walletId,\n 'signTransaction — Nightly combines signing and submission. Use submitTransaction instead.',\n );\n }\n\n /**\n * Submit a transaction.\n *\n * Nightly uses callback-based submitTransactionCommand.\n * The signedTx should be a TransactionCommand object created via\n * createTransferCommand or createTransactionChoiceCommand.\n */\n async submitTransaction(\n ctx: AdapterContext,\n session: Session,\n params: SubmitTransactionParams,\n ): Promise<TxReceipt> {\n try {\n if (!this.wallet) {\n throw new Error('Not connected to Nightly Wallet');\n }\n\n ctx.logger.debug('Submitting transaction with Nightly Wallet', {\n sessionId: session.sessionId,\n });\n\n const txCommand = params.signedTx as TransactionCommand;\n\n const result = await new Promise<{ signature?: string; updateId?: string }>(\n (resolve, reject) => {\n this.wallet!.submitTransactionCommand(txCommand, (response) => {\n if (\n response.type === SignRequestResponseType.SIGN_REQUEST_APPROVED\n ) {\n resolve(\n response.data as { signature?: string; updateId?: string },\n );\n } else if (\n response.type === SignRequestResponseType.SIGN_REQUEST_REJECTED\n ) {\n const data = response.data as { reason: string };\n reject(new Error(`Transaction rejected: ${data.reason}`));\n } else {\n const data = response.data as { error: string };\n reject(new Error(`Transaction error: ${data.error}`));\n }\n });\n },\n );\n\n const hash =\n result.updateId ||\n result.signature ||\n `tx_${Date.now()}_${Math.random().toString(36).substring(2, 10)}`;\n\n return {\n transactionHash: toTransactionHash(hash),\n submittedAt: Date.now(),\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'submitTransaction',\n transport: 'injected',\n details: { sessionId: session.sessionId },\n });\n }\n }\n\n /**\n * Proxy a Ledger API request through the Nightly Wallet.\n *\n * Nightly's canton provider may expose ledgerApi or a generic request()\n * method. We check at runtime — the interface is cast to include these\n * optional methods that may be present in newer wallet versions.\n */\n async ledgerApi(\n ctx: AdapterContext,\n session: Session,\n params: LedgerApiParams,\n ): Promise<LedgerApiResult> {\n try {\n const provider = window.nightly?.canton as unknown as\n | (NightlyCantonProvider & {\n ledgerApi?: (p: { requestMethod: string; resource: string; body?: string }) => Promise<unknown>;\n request?: (args: { method: string; params?: unknown }) => Promise<unknown>;\n })\n | undefined;\n\n if (!provider) {\n throw new Error('Not connected to Nightly Wallet');\n }\n\n ctx.logger.debug('Proxying ledger API request via Nightly Wallet', {\n sessionId: session.sessionId,\n requestMethod: params.requestMethod,\n resource: params.resource,\n });\n\n if (typeof provider.ledgerApi === 'function') {\n const result = await provider.ledgerApi({\n requestMethod: params.requestMethod,\n resource: params.resource,\n body: params.body,\n });\n const response = result as { response?: string } | string;\n return {\n response: typeof response === 'string'\n ? response\n : (response?.response ?? JSON.stringify(response)),\n };\n }\n\n if (typeof provider.request === 'function') {\n const result = await provider.request({\n method: 'ledgerApi',\n params: {\n requestMethod: params.requestMethod,\n resource: params.resource,\n body: params.body,\n },\n });\n const response = result as { response?: string } | string;\n return {\n response: typeof response === 'string'\n ? response\n : (response?.response ?? JSON.stringify(response)),\n };\n }\n\n throw new CapabilityNotSupportedError(\n this.walletId,\n 'ledgerApi — update Nightly Wallet to a version that supports CIP-0103 ledgerApi',\n );\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'ledgerApi',\n transport: 'injected',\n details: { sessionId: session.sessionId },\n });\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/nightly-adapter.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Nightly Wallet adapter implementation\n *\n * Nightly is a multichain wallet with Canton Network support.\n * The wallet injects at window.nightly.canton and uses a custom\n * (non-CIP-0103) interface with callback-based signing.\n *\n * Reference: https://docs.nightly.app/docs/canton/canton/connect/\n * Template: https://github.com/nightly-labs/canton-web3-template\n */\n\nimport type {\n WalletAdapter,\n AdapterContext,\n AdapterDetectResult,\n AdapterConnectResult,\n SignMessageParams,\n SignTransactionParams,\n SubmitTransactionParams,\n SignedMessage,\n SignedTransaction,\n TxReceipt,\n LedgerApiParams,\n LedgerApiResult,\n Session,\n PersistedSession,\n CapabilityKey,\n PartyId,\n} from '@partylayer/core';\nimport {\n toWalletId,\n toPartyId,\n toTransactionHash,\n toSignature,\n WalletNotInstalledError,\n CapabilityNotSupportedError,\n mapUnknownErrorToPartyLayerError,\n} from '@partylayer/core';\n\n// ─── Nightly Canton Types ───────────────────────────────────────────────────\n\n/** Sign request response types from Nightly wallet */\nenum SignRequestResponseType {\n SIGN_REQUEST_APPROVED = 'sign_request_approved',\n SIGN_REQUEST_REJECTED = 'sign_request_rejected',\n SIGN_REQUEST_ERROR = 'sign_request_error',\n}\n\ninterface SignRequestResponse {\n type: SignRequestResponseType;\n data:\n | { signature?: string; updateId?: string }\n | { reason: string }\n | { error: string };\n}\n\ninterface Instrument {\n id: string;\n admin: string;\n}\n\ninterface TransactionCommand {\n command: unknown;\n disclosedContracts: unknown[];\n}\n\ninterface CreateTransferCommandParams {\n receiverPartyId: string;\n amount: string;\n instrument: Instrument;\n memo?: string;\n expiryDate?: string;\n}\n\n/** The wallet object returned after successful connection */\ninterface NightlyCantonWallet {\n partyId: string;\n publicKey: string;\n signMessage: (\n message: string,\n onResponse: (response: SignRequestResponse) => void,\n ) => void;\n createTransferCommand: (\n params: CreateTransferCommandParams,\n ) => Promise<TransactionCommand>;\n submitTransactionCommand: (\n transactionCommand: TransactionCommand,\n onResponse: (response: SignRequestResponse) => void,\n ) => void;\n getPendingTransactions: () => Promise<unknown[] | null>;\n getHoldingUtxos: () => Promise<unknown[] | null>;\n}\n\n/** The injected provider at window.nightly.canton */\ninterface NightlyCantonProvider extends NightlyCantonWallet {\n connect: () => Promise<{ partyId: string; publicKey: string }>;\n disconnect: () => Promise<void>;\n isConnected: () => boolean;\n}\n\ndeclare global {\n interface Window {\n nightly?: {\n canton?: NightlyCantonProvider;\n };\n }\n}\n\n// ─── Adapter ────────────────────────────────────────────────────────────────\n\n/**\n * Nightly Wallet adapter\n *\n * Implements WalletAdapter interface for Nightly Wallet's Canton support.\n * The wallet injects at window.nightly.canton and provides:\n * - connect/disconnect via Promise\n * - signMessage via callback\n * - transaction commands via callback\n * - session restore via isConnected()\n */\nexport class NightlyAdapter implements WalletAdapter {\n readonly walletId = toWalletId('nightly');\n readonly name = 'Nightly';\n\n private wallet: NightlyCantonWallet | null = null;\n\n getCapabilities(): CapabilityKey[] {\n return [\n 'connect',\n 'disconnect',\n 'restore',\n 'signMessage',\n 'submitTransaction',\n 'ledgerApi',\n 'events',\n 'injected',\n ];\n }\n\n /**\n * Detect if Nightly wallet extension is installed.\n * Checks for window.nightly.canton provider.\n */\n async detectInstalled(): Promise<AdapterDetectResult> {\n if (typeof window === 'undefined') {\n return { installed: false, reason: 'Browser environment required' };\n }\n\n if (window.nightly?.canton) {\n return {\n installed: true,\n reason: 'Nightly wallet detected',\n };\n }\n\n return {\n installed: false,\n reason:\n 'Nightly wallet not detected. Install from https://nightly.app/download',\n };\n }\n\n /**\n * Connect to Nightly Wallet.\n *\n * Calls window.nightly.canton.connect() which opens the extension\n * popup for user approval.\n */\n async connect(\n ctx: AdapterContext,\n _opts?: { timeoutMs?: number; partyId?: PartyId },\n ): Promise<AdapterConnectResult> {\n try {\n const provider = window.nightly?.canton;\n if (!provider) {\n throw new WalletNotInstalledError(\n this.walletId,\n 'Nightly wallet not detected. Install from https://nightly.app/download',\n );\n }\n\n ctx.logger.debug('Connecting to Nightly Wallet', {\n appName: ctx.appName,\n network: ctx.network,\n });\n\n // connect() opens the extension popup for approval\n await provider.connect();\n\n // After connect, the provider itself acts as the wallet\n this.wallet = provider;\n const partyId = toPartyId(provider.partyId);\n\n ctx.logger.info('Connected to Nightly Wallet', {\n partyId: provider.partyId,\n });\n\n return {\n partyId,\n session: {\n walletId: this.walletId,\n // The Nightly provider does not report the connected network → not\n // wallet-reported, so network-mismatch detection is limited for this\n // adapter (echoes the requested ctx.network).\n network: ctx.network,\n createdAt: Date.now(),\n metadata: {\n publicKey: provider.publicKey,\n },\n },\n capabilities: this.getCapabilities(),\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'connect',\n transport: 'injected',\n details: { origin: ctx.origin, network: ctx.network },\n });\n }\n }\n\n /**\n * Disconnect from Nightly Wallet.\n */\n async disconnect(ctx: AdapterContext, _session: Session): Promise<void> {\n try {\n await window.nightly?.canton?.disconnect();\n } catch (err) {\n ctx.logger.warn('Error during Nightly wallet disconnect', err);\n }\n this.wallet = null;\n }\n\n /**\n * Restore session — check if Nightly is still connected.\n */\n async restore(\n ctx: AdapterContext,\n persisted: PersistedSession,\n ): Promise<Session | null> {\n try {\n if (typeof window === 'undefined') return null;\n\n if (persisted.expiresAt && Date.now() >= persisted.expiresAt) {\n return null;\n }\n\n const provider = window.nightly?.canton;\n if (!provider) return null;\n\n // Check if the wallet reports being connected\n if (typeof provider.isConnected === 'function' && provider.isConnected()) {\n this.wallet = provider;\n ctx.logger.debug('Restored Nightly Wallet session', {\n partyId: provider.partyId,\n });\n return { ...persisted, walletId: this.walletId };\n }\n\n return null;\n } catch (err) {\n ctx.logger.warn('Failed to restore Nightly wallet session', err);\n return null;\n }\n }\n\n /**\n * Sign a message.\n *\n * Nightly uses a callback-based signMessage API — we wrap it\n * in a Promise for the WalletAdapter interface.\n */\n async signMessage(\n ctx: AdapterContext,\n session: Session,\n params: SignMessageParams,\n ): Promise<SignedMessage> {\n try {\n if (!this.wallet) {\n throw new Error('Not connected to Nightly Wallet');\n }\n\n ctx.logger.debug('Signing message with Nightly Wallet', {\n sessionId: session.sessionId,\n messageLength: params.message.length,\n });\n\n const signature = await new Promise<string>((resolve, reject) => {\n this.wallet!.signMessage(params.message, (response) => {\n if (response.type === SignRequestResponseType.SIGN_REQUEST_APPROVED) {\n const data = response.data as { signature?: string };\n resolve(data.signature || '');\n } else if (\n response.type === SignRequestResponseType.SIGN_REQUEST_REJECTED\n ) {\n const data = response.data as { reason: string };\n reject(new Error(`Sign rejected: ${data.reason}`));\n } else {\n const data = response.data as { error: string };\n reject(new Error(`Sign error: ${data.error}`));\n }\n });\n });\n\n return {\n signature: toSignature(signature),\n partyId: session.partyId,\n message: params.message,\n nonce: params.nonce,\n domain: params.domain,\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'signMessage',\n transport: 'injected',\n details: { sessionId: session.sessionId },\n });\n }\n }\n\n /**\n * Sign a transaction — not supported standalone.\n *\n * Nightly combines signing and submission via submitTransactionCommand.\n */\n async signTransaction(\n _ctx: AdapterContext,\n _session: Session,\n _params: SignTransactionParams,\n ): Promise<SignedTransaction> {\n throw new CapabilityNotSupportedError(\n this.walletId,\n 'signTransaction — Nightly combines signing and submission. Use submitTransaction instead.',\n );\n }\n\n /**\n * Submit a transaction.\n *\n * Nightly uses callback-based submitTransactionCommand.\n * The signedTx should be a TransactionCommand object created via\n * createTransferCommand or createTransactionChoiceCommand.\n */\n async submitTransaction(\n ctx: AdapterContext,\n session: Session,\n params: SubmitTransactionParams,\n ): Promise<TxReceipt> {\n try {\n if (!this.wallet) {\n throw new Error('Not connected to Nightly Wallet');\n }\n\n ctx.logger.debug('Submitting transaction with Nightly Wallet', {\n sessionId: session.sessionId,\n });\n\n const txCommand = params.signedTx as TransactionCommand;\n\n const result = await new Promise<{ signature?: string; updateId?: string }>(\n (resolve, reject) => {\n this.wallet!.submitTransactionCommand(txCommand, (response) => {\n if (\n response.type === SignRequestResponseType.SIGN_REQUEST_APPROVED\n ) {\n resolve(\n response.data as { signature?: string; updateId?: string },\n );\n } else if (\n response.type === SignRequestResponseType.SIGN_REQUEST_REJECTED\n ) {\n const data = response.data as { reason: string };\n reject(new Error(`Transaction rejected: ${data.reason}`));\n } else {\n const data = response.data as { error: string };\n reject(new Error(`Transaction error: ${data.error}`));\n }\n });\n },\n );\n\n const hash =\n result.updateId ||\n result.signature ||\n `tx_${Date.now()}_${Math.random().toString(36).substring(2, 10)}`;\n\n return {\n transactionHash: toTransactionHash(hash),\n submittedAt: Date.now(),\n };\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'submitTransaction',\n transport: 'injected',\n details: { sessionId: session.sessionId },\n });\n }\n }\n\n /**\n * Proxy a Ledger API request through the Nightly Wallet.\n *\n * Nightly's canton provider may expose ledgerApi or a generic request()\n * method. We check at runtime — the interface is cast to include these\n * optional methods that may be present in newer wallet versions.\n */\n async ledgerApi(\n ctx: AdapterContext,\n session: Session,\n params: LedgerApiParams,\n ): Promise<LedgerApiResult> {\n try {\n const provider = window.nightly?.canton as unknown as\n | (NightlyCantonProvider & {\n ledgerApi?: (p: { requestMethod: string; resource: string; body?: string }) => Promise<unknown>;\n request?: (args: { method: string; params?: unknown }) => Promise<unknown>;\n })\n | undefined;\n\n if (!provider) {\n throw new Error('Not connected to Nightly Wallet');\n }\n\n ctx.logger.debug('Proxying ledger API request via Nightly Wallet', {\n sessionId: session.sessionId,\n requestMethod: params.requestMethod,\n resource: params.resource,\n });\n\n if (typeof provider.ledgerApi === 'function') {\n const result = await provider.ledgerApi({\n requestMethod: params.requestMethod,\n resource: params.resource,\n body: params.body,\n });\n const response = result as { response?: string } | string;\n return {\n response: typeof response === 'string'\n ? response\n : (response?.response ?? JSON.stringify(response)),\n };\n }\n\n if (typeof provider.request === 'function') {\n const result = await provider.request({\n method: 'ledgerApi',\n params: {\n requestMethod: params.requestMethod,\n resource: params.resource,\n body: params.body,\n },\n });\n const response = result as { response?: string } | string;\n return {\n response: typeof response === 'string'\n ? response\n : (response?.response ?? JSON.stringify(response)),\n };\n }\n\n throw new CapabilityNotSupportedError(\n this.walletId,\n 'ledgerApi — update Nightly Wallet to a version that supports CIP-0103 ledgerApi',\n );\n } catch (err) {\n throw mapUnknownErrorToPartyLayerError(err, {\n walletId: this.walletId,\n phase: 'ledgerApi',\n transport: 'injected',\n details: { sessionId: session.sessionId },\n });\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@partylayer/adapter-nightly",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.11",
|
|
4
4
|
"description": "Nightly Wallet adapter for PartyLayer",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"url": "https://github.com/PartyLayer/PartyLayer/issues"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@partylayer/core": "^0.
|
|
35
|
+
"@partylayer/core": "^0.5.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/node": "^20.11.0",
|