@txnlab/use-wallet-kmd 5.0.0-rc.4 → 5.0.1

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.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import algosdk from "algosdk";
2
2
  import { AdapterConstructorParams, BaseWallet, WalletAccount, WalletMetadata } from "@txnlab/use-wallet/adapter";
3
3
  import { WalletAdapterConfig, WalletFactoryOptions } from "@txnlab/use-wallet";
4
-
5
4
  //#region src/adapter.d.ts
6
5
  interface KmdConstructor {
7
6
  token: string | algosdk.KMDTokenHeader | algosdk.CustomTokenHeader;
@@ -13,7 +12,7 @@ interface KmdConstructor {
13
12
  type KmdOptions = Partial<Pick<KmdConstructor, 'token' | 'promptForPassword'>> & Omit<KmdConstructor, 'token' | 'promptForPassword'> & {
14
13
  wallet?: string;
15
14
  };
16
- declare class KmdAdapter extends BaseWallet<KmdOptions> {
15
+ export declare class KmdAdapter extends BaseWallet<KmdOptions> {
17
16
  private client;
18
17
  private kmdOptions;
19
18
  private walletName;
@@ -36,8 +35,8 @@ declare class KmdAdapter extends BaseWallet<KmdOptions> {
36
35
  }
37
36
  //#endregion
38
37
  //#region src/index.d.ts
39
- declare const WALLET_ID: "kmd";
40
- declare function kmd(options?: KmdOptions & WalletFactoryOptions): WalletAdapterConfig;
38
+ export declare const WALLET_ID: "kmd";
39
+ export declare function kmd(options?: KmdOptions & WalletFactoryOptions): WalletAdapterConfig;
41
40
  //#endregion
42
- export { KmdAdapter, type KmdOptions, WALLET_ID, kmd };
41
+ export type { KmdOptions };
43
42
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -98,7 +98,8 @@ var KmdAdapter = class extends BaseWallet {
98
98
  processEncodedTxns(txnGroup, indexesToSign) {
99
99
  const txnsToSign = [];
100
100
  txnGroup.forEach((txnBuffer, index) => {
101
- const isSigned = isSignedTxn(algosdk.msgpackRawDecode(txnBuffer));
101
+ const decodedObj = algosdk.msgpackRawDecode(txnBuffer);
102
+ const isSigned = isSignedTxn(decodedObj);
102
103
  const txn = isSigned ? algosdk.decodeSignedTransaction(txnBuffer).txn : algosdk.decodeUnsignedTransaction(txnBuffer);
103
104
  const isIndexMatch = !indexesToSign || indexesToSign.includes(index);
104
105
  const signer = txn.sender.toString();
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 400 400\" xmlns=\"http://www.w3.org/2000/svg\">\n <linearGradient id=\"algokitGradient\" gradientUnits=\"userSpaceOnUse\" x1=\"0\" y1=\"400\" x2=\"400\" y2=\"0\">\n <stop offset=\"0\" style=\"stop-color:#31D8EE\"/>\n <stop offset=\"1\" style=\"stop-color:#01DC94\"/>\n </linearGradient>\n <rect fill=\"url(#algokitGradient)\" width=\"400\" height=\"400\" />\n <path fill=\"#FFFFFF\" d=\"M309.2,309.3H275l-22.2-82.7l-47.9,82.7h-38.3l73.9-128l-11.9-44.5l-99.6,172.6H90.8L217.1,90.6 h33.5l14.7,54.3h34.6l-23.6,41L309.2,309.3z\" />\n</svg>\n`\n","import algosdk from 'algosdk'\nimport {\n BaseWallet,\n flattenTxnGroup,\n isSignedTxn,\n isTransactionArray,\n type AdapterConstructorParams,\n type WalletAccount,\n type WalletMetadata,\n type WalletState\n} from '@txnlab/use-wallet/adapter'\n\ninterface KmdConstructor {\n token: string | algosdk.KMDTokenHeader | algosdk.CustomTokenHeader\n baseServer?: string\n port?: string | number\n headers?: Record<string, string>\n promptForPassword: () => Promise<string>\n}\n\nexport type KmdOptions = Partial<Pick<KmdConstructor, 'token' | 'promptForPassword'>> &\n Omit<KmdConstructor, 'token' | 'promptForPassword'> & {\n wallet?: string\n }\n\ninterface KmdWalletRecord {\n id: string\n name: string\n driver_name?: string\n driver_version?: number\n mnemonic_ux?: boolean\n supported_txs?: Array<any>\n}\n\ninterface ListWalletsResponse {\n wallets: KmdWalletRecord[]\n message?: string\n error?: boolean\n}\n\ninterface InitWalletHandleResponse {\n wallet_handle_token: string\n message?: string\n error?: boolean\n}\n\ninterface ListKeysResponse {\n addresses: string[]\n message?: string\n error?: boolean\n}\n\nimport { icon } from './icon'\n\nconst ICON = `data:image/svg+xml;base64,${btoa(icon)}`\n\nexport class KmdAdapter extends BaseWallet<KmdOptions> {\n private client: algosdk.Kmd | null = null\n private kmdOptions: KmdConstructor\n private walletName: string\n private kmdWalletId: string = ''\n private password: string | null = null\n\n constructor(params: AdapterConstructorParams<KmdOptions>) {\n super(params)\n\n const {\n token = 'a'.repeat(64),\n baseServer = 'http://127.0.0.1',\n port = 4002,\n wallet = 'unencrypted-default-wallet',\n promptForPassword = () => Promise.resolve(prompt('KMD password') || '')\n } = this.options || {}\n\n this.kmdOptions = { token, baseServer, port, promptForPassword }\n this.walletName = wallet\n }\n\n static defaultMetadata: WalletMetadata = {\n name: 'KMD',\n icon: ICON\n }\n\n private async initializeClient(): Promise<algosdk.Kmd> {\n this.logger.info('Initializing client...')\n const { token, baseServer, port } = this.kmdOptions\n const client = new algosdk.Kmd(token, baseServer, port)\n this.client = client\n this.logger.info('Client initialized')\n return client\n }\n\n public connect = async (): Promise<WalletAccount[]> => {\n this.logger.info('Connecting...')\n if (!this.client) {\n await this.initializeClient()\n }\n\n try {\n // Get token and fetch accounts\n const token = await this.fetchToken()\n const accounts = await this.fetchAccounts(token)\n\n if (accounts.length === 0) {\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 // Release token\n await this.releaseToken(token)\n\n this.logger.info('Connected successfully', walletState)\n return walletAccounts\n } catch (error: any) {\n this.logger.error('Error connecting:', error.message)\n throw error\n }\n }\n\n public disconnect = async (): Promise<void> => {\n this.logger.info('Disconnecting...')\n this.onDisconnect()\n this.logger.info('Disconnected')\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 this.logger.info('Resuming session...')\n await this.initializeClient()\n this.logger.info('Session resumed')\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 ): algosdk.Transaction[] {\n const txnsToSign: algosdk.Transaction[] = []\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 }\n })\n\n return txnsToSign\n }\n\n private processEncodedTxns(\n txnGroup: Uint8Array[],\n indexesToSign?: number[]\n ): algosdk.Transaction[] {\n const txnsToSign: algosdk.Transaction[] = []\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 }\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: algosdk.Transaction[] = []\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 // Get token and password\n const token = await this.fetchToken()\n const password = await this.getPassword()\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 Promise.all(\n txnsToSign.map((txn) => client.signTransaction(token, password, txn))\n )\n\n this.logger.debug('Received signed transactions from wallet', signedTxns)\n\n // Release token\n await this.releaseToken(token)\n\n this.logger.debug('Transactions signed successfully', signedTxns)\n return signedTxns\n } catch (error: any) {\n this.logger.error('Error signing transactions:', error.message)\n throw error\n }\n }\n\n private async fetchWalletId(): Promise<string> {\n this.logger.debug('Fetching wallet data...', { walletName: this.walletName })\n const client = this.client || (await this.initializeClient())\n\n const { wallets }: ListWalletsResponse = await client.listWallets()\n const wallet = wallets.find((wallet: KmdWalletRecord) => wallet.name === this.walletName)\n\n if (!wallet) {\n this.logger.error(`Wallet \"${this.walletName}\" not found!`)\n throw new Error(`Wallet \"${this.walletName}\" not found!`)\n }\n\n this.kmdWalletId = wallet.id\n this.logger.debug('Wallet data fetched successfully', { walletId: this.kmdWalletId })\n return wallet.id\n }\n\n private async fetchToken(): Promise<string> {\n this.logger.debug('Fetching token...', { walletId: this.kmdWalletId })\n const client = this.client || (await this.initializeClient())\n\n const walletId = this.kmdWalletId || (await this.fetchWalletId())\n const password = await this.getPassword()\n\n const { wallet_handle_token }: InitWalletHandleResponse = await client.initWalletHandle(\n walletId,\n password\n )\n this.logger.debug('Token fetched successfully')\n return wallet_handle_token\n }\n\n private async releaseToken(token: string): Promise<void> {\n this.logger.debug('Releasing token...')\n const client = this.client || (await this.initializeClient())\n await client.releaseWalletHandle(token)\n this.logger.debug('Token released successfully')\n }\n\n private async getPassword(): Promise<string> {\n if (this.password !== null) {\n return this.password\n }\n const password = await this.kmdOptions.promptForPassword()\n this.password = password\n return password\n }\n\n private async fetchAccounts(token: string): Promise<string[]> {\n this.logger.debug('Fetching accounts...')\n const client = this.client || (await this.initializeClient())\n const { addresses }: ListKeysResponse = await client.listKeys(token)\n this.logger.debug('Accounts fetched successfully', { addresses })\n return addresses\n }\n}\n","import { KmdAdapter } from './adapter'\nimport type { KmdOptions } from './adapter'\nimport type { WalletAdapterConfig, WalletFactoryOptions } from '@txnlab/use-wallet'\n\nexport const WALLET_ID = 'kmd' as const\n\nexport function kmd(options?: KmdOptions & WalletFactoryOptions): WalletAdapterConfig {\n const { metadata, ...adapterOptions } = options ?? {}\n return {\n id: WALLET_ID,\n metadata: { ...KmdAdapter.defaultMetadata, ...metadata },\n Adapter: KmdAdapter 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: ['localnet'] }\n }\n}\n\nexport { KmdAdapter }\nexport type { KmdOptions }\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 400 400\" xmlns=\"http://www.w3.org/2000/svg\">\n <linearGradient id=\"algokitGradient\" gradientUnits=\"userSpaceOnUse\" x1=\"0\" y1=\"400\" x2=\"400\" y2=\"0\">\n <stop offset=\"0\" style=\"stop-color:#31D8EE\"/>\n <stop offset=\"1\" style=\"stop-color:#01DC94\"/>\n </linearGradient>\n <rect fill=\"url(#algokitGradient)\" width=\"400\" height=\"400\" />\n <path fill=\"#FFFFFF\" d=\"M309.2,309.3H275l-22.2-82.7l-47.9,82.7h-38.3l73.9-128l-11.9-44.5l-99.6,172.6H90.8L217.1,90.6 h33.5l14.7,54.3h34.6l-23.6,41L309.2,309.3z\" />\n</svg>\n`\n","import algosdk from 'algosdk'\nimport {\n BaseWallet,\n flattenTxnGroup,\n isSignedTxn,\n isTransactionArray,\n type AdapterConstructorParams,\n type WalletAccount,\n type WalletMetadata,\n type WalletState\n} from '@txnlab/use-wallet/adapter'\n\ninterface KmdConstructor {\n token: string | algosdk.KMDTokenHeader | algosdk.CustomTokenHeader\n baseServer?: string\n port?: string | number\n headers?: Record<string, string>\n promptForPassword: () => Promise<string>\n}\n\nexport type KmdOptions = Partial<Pick<KmdConstructor, 'token' | 'promptForPassword'>> &\n Omit<KmdConstructor, 'token' | 'promptForPassword'> & {\n wallet?: string\n }\n\ninterface KmdWalletRecord {\n id: string\n name: string\n driver_name?: string\n driver_version?: number\n mnemonic_ux?: boolean\n supported_txs?: Array<any>\n}\n\ninterface ListWalletsResponse {\n wallets: KmdWalletRecord[]\n message?: string\n error?: boolean\n}\n\ninterface InitWalletHandleResponse {\n wallet_handle_token: string\n message?: string\n error?: boolean\n}\n\ninterface ListKeysResponse {\n addresses: string[]\n message?: string\n error?: boolean\n}\n\nimport { icon } from './icon'\n\nconst ICON = `data:image/svg+xml;base64,${btoa(icon)}`\n\nexport class KmdAdapter extends BaseWallet<KmdOptions> {\n private client: algosdk.Kmd | null = null\n private kmdOptions: KmdConstructor\n private walletName: string\n private kmdWalletId: string = ''\n private password: string | null = null\n\n constructor(params: AdapterConstructorParams<KmdOptions>) {\n super(params)\n\n const {\n token = 'a'.repeat(64),\n baseServer = 'http://127.0.0.1',\n port = 4002,\n wallet = 'unencrypted-default-wallet',\n promptForPassword = () => Promise.resolve(prompt('KMD password') || '')\n } = this.options || {}\n\n this.kmdOptions = { token, baseServer, port, promptForPassword }\n this.walletName = wallet\n }\n\n static defaultMetadata: WalletMetadata = {\n name: 'KMD',\n icon: ICON\n }\n\n private async initializeClient(): Promise<algosdk.Kmd> {\n this.logger.info('Initializing client...')\n const { token, baseServer, port } = this.kmdOptions\n const client = new algosdk.Kmd(token, baseServer, port)\n this.client = client\n this.logger.info('Client initialized')\n return client\n }\n\n public connect = async (): Promise<WalletAccount[]> => {\n this.logger.info('Connecting...')\n if (!this.client) {\n await this.initializeClient()\n }\n\n try {\n // Get token and fetch accounts\n const token = await this.fetchToken()\n const accounts = await this.fetchAccounts(token)\n\n if (accounts.length === 0) {\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 // Release token\n await this.releaseToken(token)\n\n this.logger.info('Connected successfully', walletState)\n return walletAccounts\n } catch (error: any) {\n this.logger.error('Error connecting:', error.message)\n throw error\n }\n }\n\n public disconnect = async (): Promise<void> => {\n this.logger.info('Disconnecting...')\n this.onDisconnect()\n this.logger.info('Disconnected')\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 this.logger.info('Resuming session...')\n await this.initializeClient()\n this.logger.info('Session resumed')\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 ): algosdk.Transaction[] {\n const txnsToSign: algosdk.Transaction[] = []\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 }\n })\n\n return txnsToSign\n }\n\n private processEncodedTxns(\n txnGroup: Uint8Array[],\n indexesToSign?: number[]\n ): algosdk.Transaction[] {\n const txnsToSign: algosdk.Transaction[] = []\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 }\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: algosdk.Transaction[] = []\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 // Get token and password\n const token = await this.fetchToken()\n const password = await this.getPassword()\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 Promise.all(\n txnsToSign.map((txn) => client.signTransaction(token, password, txn))\n )\n\n this.logger.debug('Received signed transactions from wallet', signedTxns)\n\n // Release token\n await this.releaseToken(token)\n\n this.logger.debug('Transactions signed successfully', signedTxns)\n return signedTxns\n } catch (error: any) {\n this.logger.error('Error signing transactions:', error.message)\n throw error\n }\n }\n\n private async fetchWalletId(): Promise<string> {\n this.logger.debug('Fetching wallet data...', { walletName: this.walletName })\n const client = this.client || (await this.initializeClient())\n\n const { wallets }: ListWalletsResponse = await client.listWallets()\n const wallet = wallets.find((wallet: KmdWalletRecord) => wallet.name === this.walletName)\n\n if (!wallet) {\n this.logger.error(`Wallet \"${this.walletName}\" not found!`)\n throw new Error(`Wallet \"${this.walletName}\" not found!`)\n }\n\n this.kmdWalletId = wallet.id\n this.logger.debug('Wallet data fetched successfully', { walletId: this.kmdWalletId })\n return wallet.id\n }\n\n private async fetchToken(): Promise<string> {\n this.logger.debug('Fetching token...', { walletId: this.kmdWalletId })\n const client = this.client || (await this.initializeClient())\n\n const walletId = this.kmdWalletId || (await this.fetchWalletId())\n const password = await this.getPassword()\n\n const { wallet_handle_token }: InitWalletHandleResponse = await client.initWalletHandle(\n walletId,\n password\n )\n this.logger.debug('Token fetched successfully')\n return wallet_handle_token\n }\n\n private async releaseToken(token: string): Promise<void> {\n this.logger.debug('Releasing token...')\n const client = this.client || (await this.initializeClient())\n await client.releaseWalletHandle(token)\n this.logger.debug('Token released successfully')\n }\n\n private async getPassword(): Promise<string> {\n if (this.password !== null) {\n return this.password\n }\n const password = await this.kmdOptions.promptForPassword()\n this.password = password\n return password\n }\n\n private async fetchAccounts(token: string): Promise<string[]> {\n this.logger.debug('Fetching accounts...')\n const client = this.client || (await this.initializeClient())\n const { addresses }: ListKeysResponse = await client.listKeys(token)\n this.logger.debug('Accounts fetched successfully', { addresses })\n return addresses\n }\n}\n","import { KmdAdapter } from './adapter'\nimport type { KmdOptions } from './adapter'\nimport type { WalletAdapterConfig, WalletFactoryOptions } from '@txnlab/use-wallet'\n\nexport const WALLET_ID = 'kmd' as const\n\nexport function kmd(options?: KmdOptions & WalletFactoryOptions): WalletAdapterConfig {\n const { metadata, ...adapterOptions } = options ?? {}\n return {\n id: WALLET_ID,\n metadata: { ...KmdAdapter.defaultMetadata, ...metadata },\n Adapter: KmdAdapter 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: ['localnet'] }\n }\n}\n\nexport { KmdAdapter }\nexport type { KmdOptions }\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@txnlab/use-wallet-kmd",
3
- "version": "5.0.0-rc.4",
3
+ "version": "5.0.1",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
@@ -35,9 +35,9 @@
35
35
  },
36
36
  "devDependencies": {
37
37
  "algosdk": "3.6.0",
38
- "tsdown": "0.21.0",
38
+ "tsdown": "0.23.0",
39
39
  "typescript": "5.9.3",
40
- "@txnlab/use-wallet": "5.0.0-rc.4"
40
+ "@txnlab/use-wallet": "5.0.1"
41
41
  },
42
42
  "scripts": {
43
43
  "build": "tsdown",