@txnlab/use-wallet-defly 5.0.0-rc.3 → 5.0.0
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/README.md +31 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/package.json +7 -3
package/README.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# @txnlab/use-wallet-defly
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@txnlab/use-wallet-defly)
|
|
4
|
+
[](https://github.com/TxnLab/use-wallet/blob/main/LICENSE)
|
|
5
|
+
|
|
6
|
+
Defly Wallet adapter for [use-wallet](https://github.com/TxnLab/use-wallet), the Algorand wallet integration library.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @txnlab/use-wallet @txnlab/use-wallet-defly
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
If you use a framework adapter (`@txnlab/use-wallet-react`, `-vue`, `-solid`, or `-svelte`), install it in place of `@txnlab/use-wallet`.
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { WalletManager } from '@txnlab/use-wallet'
|
|
20
|
+
import { defly } from '@txnlab/use-wallet-defly'
|
|
21
|
+
|
|
22
|
+
const manager = new WalletManager({
|
|
23
|
+
wallets: [defly()]
|
|
24
|
+
})
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Supports MainNet and TestNet. Options: `bridge`, `shouldShowSignTxnToast`, `chainId`.
|
|
28
|
+
|
|
29
|
+
The factory also accepts an optional `metadata` option to override the wallet's display name and icon.
|
|
30
|
+
|
|
31
|
+
### Visit [txnlab.gitbook.io/use-wallet](https://txnlab.gitbook.io/use-wallet) for docs, guides, and examples!
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import algosdk from "algosdk";
|
|
2
2
|
import { AdapterConstructorParams, BaseWallet, WalletAccount, WalletMetadata } from "@txnlab/use-wallet/adapter";
|
|
3
|
-
import { WalletAdapterConfig } from "@txnlab/use-wallet";
|
|
3
|
+
import { WalletAdapterConfig, WalletFactoryOptions } from "@txnlab/use-wallet";
|
|
4
4
|
|
|
5
5
|
//#region src/adapter.d.ts
|
|
6
6
|
interface DeflyOptions {
|
|
@@ -25,7 +25,7 @@ declare class DeflyAdapter extends BaseWallet<DeflyOptions> {
|
|
|
25
25
|
//#endregion
|
|
26
26
|
//#region src/index.d.ts
|
|
27
27
|
declare const WALLET_ID: "defly";
|
|
28
|
-
declare function defly(options?: DeflyOptions): WalletAdapterConfig;
|
|
28
|
+
declare function defly(options?: DeflyOptions & WalletFactoryOptions): WalletAdapterConfig;
|
|
29
29
|
//#endregion
|
|
30
30
|
export { DeflyAdapter, type DeflyOptions, WALLET_ID, defly };
|
|
31
31
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -192,11 +192,15 @@ var DeflyAdapter = class extends BaseWallet {
|
|
|
192
192
|
//#region src/index.ts
|
|
193
193
|
const WALLET_ID = "defly";
|
|
194
194
|
function defly(options) {
|
|
195
|
+
const { metadata, ...adapterOptions } = options ?? {};
|
|
195
196
|
return {
|
|
196
197
|
id: WALLET_ID,
|
|
197
|
-
metadata:
|
|
198
|
+
metadata: {
|
|
199
|
+
...DeflyAdapter.defaultMetadata,
|
|
200
|
+
...metadata
|
|
201
|
+
},
|
|
198
202
|
Adapter: DeflyAdapter,
|
|
199
|
-
options,
|
|
203
|
+
options: Object.keys(adapterOptions).length > 0 ? adapterOptions : void 0,
|
|
200
204
|
capabilities: { supportedNetworks: ["mainnet", "testnet"] }
|
|
201
205
|
};
|
|
202
206
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/icon.ts","../src/adapter.ts","../src/index.ts"],"sourcesContent":["export const icon = `\n<svg viewBox=\"0 0 1024 1024\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"1024\" height=\"1024\" />\n <path fill=\"#FFFFFF\" d=\"M779.9,684.4L512,230L244.1,684.4L512,529.5L779.9,684.4z\" />\n <path fill=\"#FFFFFF\" d=\"M733.1,730L512,613.5L290.9,730L512,658L733.1,730z\" />\n</svg>\n`\n","import algosdk from 'algosdk'\nimport {\n BaseWallet,\n compareAccounts,\n flattenTxnGroup,\n isSignedTxn,\n isTransactionArray,\n type AdapterConstructorParams,\n type SignerTransaction,\n type WalletAccount,\n type WalletMetadata,\n type WalletState\n} from '@txnlab/use-wallet/adapter'\nimport type { DeflyWalletConnect } from '@blockshake/defly-connect'\n\nexport interface DeflyOptions {\n bridge?: string\n shouldShowSignTxnToast?: boolean\n chainId?: 416001 | 416002 | 416003 | 4160\n}\n\nimport { icon } from './icon'\n\nconst ICON = `data:image/svg+xml;base64,${btoa(icon)}`\n\nexport class DeflyAdapter extends BaseWallet<DeflyOptions> {\n private client: DeflyWalletConnect | null = null\n\n constructor(params: AdapterConstructorParams<DeflyOptions>) {\n super(params)\n }\n\n static defaultMetadata: WalletMetadata = {\n name: 'Defly',\n icon: ICON\n }\n\n private async initializeClient(): Promise<DeflyWalletConnect> {\n this.logger.info('Initializing client...')\n const { DeflyWalletConnect } = await import('@blockshake/defly-connect')\n const client = new DeflyWalletConnect(this.options)\n this.client = client\n this.logger.info('Client initialized')\n return client\n }\n\n private manageWalletConnectSession(action: 'backup' | 'restore', targetWalletKey?: string): void {\n const key = targetWalletKey || this.walletKey\n if (typeof localStorage === 'undefined') return\n\n if (action === 'backup') {\n const data = localStorage.getItem('walletconnect')\n if (data) {\n localStorage.setItem(`walletconnect-${key}`, data)\n localStorage.removeItem('walletconnect')\n this.logger.debug(`Backed up WalletConnect session for ${key}`)\n }\n } else if (action === 'restore') {\n const data = localStorage.getItem(`walletconnect-${key}`)\n if (data) {\n localStorage.setItem('walletconnect', data)\n localStorage.removeItem(`walletconnect-${key}`)\n this.logger.debug(`Restored WalletConnect session for ${key}`)\n }\n }\n }\n\n public connect = async (): Promise<WalletAccount[]> => {\n this.logger.info('Connecting...')\n const currentActiveWallet = this.store.getActiveWallet()\n if (currentActiveWallet && currentActiveWallet !== this.id) {\n this.manageWalletConnectSession('backup', currentActiveWallet)\n }\n const client = this.client || (await this.initializeClient())\n const accounts = await client.connect()\n\n // Listen for disconnect event\n client.connector?.on('disconnect', this.onDisconnect)\n\n if (accounts.length === 0) {\n this.logger.error('No accounts found!')\n throw new Error('No accounts found!')\n }\n\n const walletAccounts = accounts.map((address: string, idx: number) => ({\n name: `${this.metadata.name} Account ${idx + 1}`,\n address\n }))\n\n const activeAccount = walletAccounts[0]\n\n const walletState: WalletState = {\n accounts: walletAccounts,\n activeAccount\n }\n\n this.store.addWallet(walletState)\n\n this.logger.info('Connected successfully', walletState)\n return walletAccounts\n }\n\n public disconnect = async (): Promise<void> => {\n this.logger.info('Disconnecting...')\n const client = this.client || (await this.initializeClient())\n\n const currentActiveWallet = this.store.getActiveWallet()\n if (currentActiveWallet && currentActiveWallet !== this.id) {\n this.manageWalletConnectSession('backup', currentActiveWallet)\n this.manageWalletConnectSession('restore', this.id)\n await client.disconnect()\n // Wait for the disconnect to complete (race condition)\n await new Promise((resolve) => setTimeout(resolve, 500))\n this.manageWalletConnectSession('restore', currentActiveWallet)\n } else {\n await client.disconnect()\n }\n\n this.onDisconnect()\n this.logger.info('Disconnected')\n }\n\n public setActive = (): void => {\n this.logger.info(`Set active wallet: ${this.id}`)\n const currentActiveWallet = this.store.getActiveWallet()\n if (currentActiveWallet && currentActiveWallet === 'pera') {\n this.manageWalletConnectSession('backup', currentActiveWallet)\n }\n this.manageWalletConnectSession('restore')\n this.store.setActive()\n }\n\n public resumeSession = async (): Promise<void> => {\n try {\n const walletState = this.store.getWalletState()\n\n // No session to resume\n if (!walletState) {\n this.logger.info('No session to resume')\n return\n }\n\n // If Pera is active, skip reconnectSession for Defly\n if (this.store.getActiveWallet() === 'pera') {\n this.logger.info('Skipping reconnectSession for Defly (inactive)')\n return\n }\n\n this.logger.info('Resuming session...')\n\n const client = this.client || (await this.initializeClient())\n const accounts = await client.reconnectSession()\n\n if (accounts.length === 0) {\n this.logger.error('No accounts found!')\n throw new Error('No accounts found!')\n }\n\n const walletAccounts = accounts.map((address: string, idx: number) => ({\n name: `${this.metadata.name} Account ${idx + 1}`,\n address\n }))\n\n const match = compareAccounts(walletAccounts, walletState.accounts)\n\n if (!match) {\n this.logger.warn('Session accounts mismatch, updating accounts', {\n prev: walletState.accounts,\n current: walletAccounts\n })\n this.store.setAccounts(walletAccounts)\n }\n this.logger.info('Session resumed successfully')\n } catch (error: any) {\n this.logger.error('Error resuming session:', error.message)\n this.onDisconnect()\n throw error\n }\n }\n\n private processTxns(\n txnGroup: algosdk.Transaction[],\n indexesToSign?: number[]\n ): SignerTransaction[] {\n const txnsToSign: SignerTransaction[] = []\n\n txnGroup.forEach((txn, index) => {\n const isIndexMatch = !indexesToSign || indexesToSign.includes(index)\n const signer = txn.sender.toString()\n const canSignTxn = this.addresses.includes(signer)\n\n if (isIndexMatch && canSignTxn) {\n txnsToSign.push({ txn })\n } else {\n txnsToSign.push({ txn, signers: [] })\n }\n })\n\n return txnsToSign\n }\n\n private processEncodedTxns(\n txnGroup: Uint8Array[],\n indexesToSign?: number[]\n ): SignerTransaction[] {\n const txnsToSign: SignerTransaction[] = []\n\n txnGroup.forEach((txnBuffer, index) => {\n const decodedObj = algosdk.msgpackRawDecode(txnBuffer)\n const isSigned = isSignedTxn(decodedObj)\n\n const txn: algosdk.Transaction = isSigned\n ? algosdk.decodeSignedTransaction(txnBuffer).txn\n : algosdk.decodeUnsignedTransaction(txnBuffer)\n\n const isIndexMatch = !indexesToSign || indexesToSign.includes(index)\n const signer = txn.sender.toString()\n const canSignTxn = !isSigned && this.addresses.includes(signer)\n\n if (isIndexMatch && canSignTxn) {\n txnsToSign.push({ txn })\n } else {\n txnsToSign.push({ txn, signers: [] })\n }\n })\n\n return txnsToSign\n }\n\n public signTransactions = async <T extends algosdk.Transaction[] | Uint8Array[]>(\n txnGroup: T | T[],\n indexesToSign?: number[]\n ): Promise<(Uint8Array | null)[]> => {\n try {\n this.logger.debug('Signing transactions...', { txnGroup, indexesToSign })\n let txnsToSign: SignerTransaction[] = []\n\n // Determine type and process transactions for signing\n if (isTransactionArray(txnGroup)) {\n const flatTxns: algosdk.Transaction[] = flattenTxnGroup(txnGroup)\n txnsToSign = this.processTxns(flatTxns, indexesToSign)\n } else {\n const flatTxns: Uint8Array[] = flattenTxnGroup(txnGroup as Uint8Array[])\n txnsToSign = this.processEncodedTxns(flatTxns, indexesToSign)\n }\n\n const client = this.client || (await this.initializeClient())\n\n this.logger.debug('Sending processed transactions to wallet...', [txnsToSign])\n\n // Sign transactions\n const signedTxns = await client.signTransaction([txnsToSign])\n this.logger.debug('Received signed transactions from wallet', signedTxns)\n\n // ARC-0001 - Return null for unsigned transactions\n const result = txnsToSign.reduce<(Uint8Array | null)[]>((acc, txn) => {\n if (txn.signers && txn.signers.length == 0) {\n acc.push(null)\n } else {\n const signedTxn = signedTxns.shift()\n if (signedTxn) {\n acc.push(signedTxn)\n }\n }\n return acc\n }, [])\n\n this.logger.debug('Transactions signed successfully', result)\n return result\n } catch (error: any) {\n this.logger.error('Error signing transactions:', error.message)\n throw error\n }\n }\n}\n","import { DeflyAdapter } from './adapter'\nimport type { DeflyOptions } from './adapter'\nimport type { WalletAdapterConfig } from '@txnlab/use-wallet'\n\nexport const WALLET_ID = 'defly' as const\n\nexport function defly(options?: DeflyOptions): WalletAdapterConfig {\n return {\n id: WALLET_ID,\n metadata: DeflyAdapter.defaultMetadata,\n Adapter: DeflyAdapter as unknown as WalletAdapterConfig['Adapter'],\n options: options as unknown as Record<string, unknown> | undefined,\n capabilities: { supportedNetworks: ['mainnet', 'testnet'] }\n }\n}\n\nexport { DeflyAdapter }\nexport type { DeflyOptions }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/icon.ts","../src/adapter.ts","../src/index.ts"],"sourcesContent":["export const icon = `\n<svg viewBox=\"0 0 1024 1024\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"1024\" height=\"1024\" />\n <path fill=\"#FFFFFF\" d=\"M779.9,684.4L512,230L244.1,684.4L512,529.5L779.9,684.4z\" />\n <path fill=\"#FFFFFF\" d=\"M733.1,730L512,613.5L290.9,730L512,658L733.1,730z\" />\n</svg>\n`\n","import algosdk from 'algosdk'\nimport {\n BaseWallet,\n compareAccounts,\n flattenTxnGroup,\n isSignedTxn,\n isTransactionArray,\n type AdapterConstructorParams,\n type SignerTransaction,\n type WalletAccount,\n type WalletMetadata,\n type WalletState\n} from '@txnlab/use-wallet/adapter'\nimport type { DeflyWalletConnect } from '@blockshake/defly-connect'\n\nexport interface DeflyOptions {\n bridge?: string\n shouldShowSignTxnToast?: boolean\n chainId?: 416001 | 416002 | 416003 | 4160\n}\n\nimport { icon } from './icon'\n\nconst ICON = `data:image/svg+xml;base64,${btoa(icon)}`\n\nexport class DeflyAdapter extends BaseWallet<DeflyOptions> {\n private client: DeflyWalletConnect | null = null\n\n constructor(params: AdapterConstructorParams<DeflyOptions>) {\n super(params)\n }\n\n static defaultMetadata: WalletMetadata = {\n name: 'Defly',\n icon: ICON\n }\n\n private async initializeClient(): Promise<DeflyWalletConnect> {\n this.logger.info('Initializing client...')\n const { DeflyWalletConnect } = await import('@blockshake/defly-connect')\n const client = new DeflyWalletConnect(this.options)\n this.client = client\n this.logger.info('Client initialized')\n return client\n }\n\n private manageWalletConnectSession(action: 'backup' | 'restore', targetWalletKey?: string): void {\n const key = targetWalletKey || this.walletKey\n if (typeof localStorage === 'undefined') return\n\n if (action === 'backup') {\n const data = localStorage.getItem('walletconnect')\n if (data) {\n localStorage.setItem(`walletconnect-${key}`, data)\n localStorage.removeItem('walletconnect')\n this.logger.debug(`Backed up WalletConnect session for ${key}`)\n }\n } else if (action === 'restore') {\n const data = localStorage.getItem(`walletconnect-${key}`)\n if (data) {\n localStorage.setItem('walletconnect', data)\n localStorage.removeItem(`walletconnect-${key}`)\n this.logger.debug(`Restored WalletConnect session for ${key}`)\n }\n }\n }\n\n public connect = async (): Promise<WalletAccount[]> => {\n this.logger.info('Connecting...')\n const currentActiveWallet = this.store.getActiveWallet()\n if (currentActiveWallet && currentActiveWallet !== this.id) {\n this.manageWalletConnectSession('backup', currentActiveWallet)\n }\n const client = this.client || (await this.initializeClient())\n const accounts = await client.connect()\n\n // Listen for disconnect event\n client.connector?.on('disconnect', this.onDisconnect)\n\n if (accounts.length === 0) {\n this.logger.error('No accounts found!')\n throw new Error('No accounts found!')\n }\n\n const walletAccounts = accounts.map((address: string, idx: number) => ({\n name: `${this.metadata.name} Account ${idx + 1}`,\n address\n }))\n\n const activeAccount = walletAccounts[0]\n\n const walletState: WalletState = {\n accounts: walletAccounts,\n activeAccount\n }\n\n this.store.addWallet(walletState)\n\n this.logger.info('Connected successfully', walletState)\n return walletAccounts\n }\n\n public disconnect = async (): Promise<void> => {\n this.logger.info('Disconnecting...')\n const client = this.client || (await this.initializeClient())\n\n const currentActiveWallet = this.store.getActiveWallet()\n if (currentActiveWallet && currentActiveWallet !== this.id) {\n this.manageWalletConnectSession('backup', currentActiveWallet)\n this.manageWalletConnectSession('restore', this.id)\n await client.disconnect()\n // Wait for the disconnect to complete (race condition)\n await new Promise((resolve) => setTimeout(resolve, 500))\n this.manageWalletConnectSession('restore', currentActiveWallet)\n } else {\n await client.disconnect()\n }\n\n this.onDisconnect()\n this.logger.info('Disconnected')\n }\n\n public setActive = (): void => {\n this.logger.info(`Set active wallet: ${this.id}`)\n const currentActiveWallet = this.store.getActiveWallet()\n if (currentActiveWallet && currentActiveWallet === 'pera') {\n this.manageWalletConnectSession('backup', currentActiveWallet)\n }\n this.manageWalletConnectSession('restore')\n this.store.setActive()\n }\n\n public resumeSession = async (): Promise<void> => {\n try {\n const walletState = this.store.getWalletState()\n\n // No session to resume\n if (!walletState) {\n this.logger.info('No session to resume')\n return\n }\n\n // If Pera is active, skip reconnectSession for Defly\n if (this.store.getActiveWallet() === 'pera') {\n this.logger.info('Skipping reconnectSession for Defly (inactive)')\n return\n }\n\n this.logger.info('Resuming session...')\n\n const client = this.client || (await this.initializeClient())\n const accounts = await client.reconnectSession()\n\n if (accounts.length === 0) {\n this.logger.error('No accounts found!')\n throw new Error('No accounts found!')\n }\n\n const walletAccounts = accounts.map((address: string, idx: number) => ({\n name: `${this.metadata.name} Account ${idx + 1}`,\n address\n }))\n\n const match = compareAccounts(walletAccounts, walletState.accounts)\n\n if (!match) {\n this.logger.warn('Session accounts mismatch, updating accounts', {\n prev: walletState.accounts,\n current: walletAccounts\n })\n this.store.setAccounts(walletAccounts)\n }\n this.logger.info('Session resumed successfully')\n } catch (error: any) {\n this.logger.error('Error resuming session:', error.message)\n this.onDisconnect()\n throw error\n }\n }\n\n private processTxns(\n txnGroup: algosdk.Transaction[],\n indexesToSign?: number[]\n ): SignerTransaction[] {\n const txnsToSign: SignerTransaction[] = []\n\n txnGroup.forEach((txn, index) => {\n const isIndexMatch = !indexesToSign || indexesToSign.includes(index)\n const signer = txn.sender.toString()\n const canSignTxn = this.addresses.includes(signer)\n\n if (isIndexMatch && canSignTxn) {\n txnsToSign.push({ txn })\n } else {\n txnsToSign.push({ txn, signers: [] })\n }\n })\n\n return txnsToSign\n }\n\n private processEncodedTxns(\n txnGroup: Uint8Array[],\n indexesToSign?: number[]\n ): SignerTransaction[] {\n const txnsToSign: SignerTransaction[] = []\n\n txnGroup.forEach((txnBuffer, index) => {\n const decodedObj = algosdk.msgpackRawDecode(txnBuffer)\n const isSigned = isSignedTxn(decodedObj)\n\n const txn: algosdk.Transaction = isSigned\n ? algosdk.decodeSignedTransaction(txnBuffer).txn\n : algosdk.decodeUnsignedTransaction(txnBuffer)\n\n const isIndexMatch = !indexesToSign || indexesToSign.includes(index)\n const signer = txn.sender.toString()\n const canSignTxn = !isSigned && this.addresses.includes(signer)\n\n if (isIndexMatch && canSignTxn) {\n txnsToSign.push({ txn })\n } else {\n txnsToSign.push({ txn, signers: [] })\n }\n })\n\n return txnsToSign\n }\n\n public signTransactions = async <T extends algosdk.Transaction[] | Uint8Array[]>(\n txnGroup: T | T[],\n indexesToSign?: number[]\n ): Promise<(Uint8Array | null)[]> => {\n try {\n this.logger.debug('Signing transactions...', { txnGroup, indexesToSign })\n let txnsToSign: SignerTransaction[] = []\n\n // Determine type and process transactions for signing\n if (isTransactionArray(txnGroup)) {\n const flatTxns: algosdk.Transaction[] = flattenTxnGroup(txnGroup)\n txnsToSign = this.processTxns(flatTxns, indexesToSign)\n } else {\n const flatTxns: Uint8Array[] = flattenTxnGroup(txnGroup as Uint8Array[])\n txnsToSign = this.processEncodedTxns(flatTxns, indexesToSign)\n }\n\n const client = this.client || (await this.initializeClient())\n\n this.logger.debug('Sending processed transactions to wallet...', [txnsToSign])\n\n // Sign transactions\n const signedTxns = await client.signTransaction([txnsToSign])\n this.logger.debug('Received signed transactions from wallet', signedTxns)\n\n // ARC-0001 - Return null for unsigned transactions\n const result = txnsToSign.reduce<(Uint8Array | null)[]>((acc, txn) => {\n if (txn.signers && txn.signers.length == 0) {\n acc.push(null)\n } else {\n const signedTxn = signedTxns.shift()\n if (signedTxn) {\n acc.push(signedTxn)\n }\n }\n return acc\n }, [])\n\n this.logger.debug('Transactions signed successfully', result)\n return result\n } catch (error: any) {\n this.logger.error('Error signing transactions:', error.message)\n throw error\n }\n }\n}\n","import { DeflyAdapter } from './adapter'\nimport type { DeflyOptions } from './adapter'\nimport type { WalletAdapterConfig, WalletFactoryOptions } from '@txnlab/use-wallet'\n\nexport const WALLET_ID = 'defly' as const\n\nexport function defly(options?: DeflyOptions & WalletFactoryOptions): WalletAdapterConfig {\n const { metadata, ...adapterOptions } = options ?? {}\n return {\n id: WALLET_ID,\n metadata: { ...DeflyAdapter.defaultMetadata, ...metadata },\n Adapter: DeflyAdapter as unknown as WalletAdapterConfig['Adapter'],\n options:\n Object.keys(adapterOptions).length > 0\n ? (adapterOptions as unknown as Record<string, unknown>)\n : undefined,\n capabilities: { supportedNetworks: ['mainnet', 'testnet'] }\n }\n}\n\nexport { DeflyAdapter }\nexport type { DeflyOptions }\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@txnlab/use-wallet-defly",
|
|
3
|
-
"version": "5.0.0
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"provenance": true
|
|
@@ -8,12 +8,16 @@
|
|
|
8
8
|
"description": "Defly Wallet adapter for @txnlab/use-wallet",
|
|
9
9
|
"author": "Doug Richar <drichar@gmail.com>",
|
|
10
10
|
"license": "MIT",
|
|
11
|
+
"engines": {
|
|
12
|
+
"node": ">=22"
|
|
13
|
+
},
|
|
11
14
|
"repository": {
|
|
12
15
|
"type": "git",
|
|
13
16
|
"url": "git+https://github.com/TxnLab/use-wallet.git",
|
|
14
17
|
"directory": "packages/wallets/defly"
|
|
15
18
|
},
|
|
16
19
|
"type": "module",
|
|
20
|
+
"sideEffects": false,
|
|
17
21
|
"main": "./dist/index.js",
|
|
18
22
|
"types": "./dist/index.d.ts",
|
|
19
23
|
"exports": {
|
|
@@ -33,10 +37,10 @@
|
|
|
33
37
|
"@blockshake/defly-connect": "1.2.1"
|
|
34
38
|
},
|
|
35
39
|
"devDependencies": {
|
|
36
|
-
"algosdk": "3.
|
|
40
|
+
"algosdk": "3.6.0",
|
|
37
41
|
"tsdown": "0.21.0",
|
|
38
42
|
"typescript": "5.9.3",
|
|
39
|
-
"@txnlab/use-wallet": "5.0.0
|
|
43
|
+
"@txnlab/use-wallet": "5.0.0"
|
|
40
44
|
},
|
|
41
45
|
"scripts": {
|
|
42
46
|
"build": "tsdown",
|