@txnlab/use-wallet 1.2.5 → 1.2.7
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 +67 -90
- package/dist/cjs/algod/index.d.ts +3 -3
- package/dist/cjs/clients/algosigner/client.d.ts +11 -6
- package/dist/cjs/clients/algosigner/types.d.ts +21 -17
- package/dist/cjs/index.js +81 -64
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/wallet.d.ts +9 -7
- package/dist/esm/algod/index.d.ts +3 -3
- package/dist/esm/clients/algosigner/client.d.ts +11 -6
- package/dist/esm/clients/algosigner/types.d.ts +21 -17
- package/dist/esm/index.js +81 -64
- package/dist/esm/types/wallet.d.ts +9 -7
- package/dist/index.d.ts +59 -20
- package/package.json +8 -1
package/README.md
CHANGED
|
@@ -46,29 +46,21 @@ npm install algosdk @blockshake/defly-connect @perawallet/connect @randlabs/myal
|
|
|
46
46
|
|
|
47
47
|
### Set up the Wallet Provider
|
|
48
48
|
|
|
49
|
-
In `app.js`, initialize the Wallet Provider so that the `useWallet` hook can be used in the child components, and use the `reconnectProviders` function to restore sessions for users returning to the app.
|
|
50
|
-
|
|
49
|
+
In `app.js`, initialize the Wallet Provider so that the `useWallet` hook can be used in the child components, and use the `reconnectProviders` function to restore sessions for users returning to the app.
|
|
51
50
|
|
|
52
51
|
```jsx
|
|
53
|
-
import React from
|
|
54
|
-
import {
|
|
55
|
-
reconnectProviders,
|
|
56
|
-
initializeProviders,
|
|
57
|
-
WalletProvider,
|
|
58
|
-
} from "@txnlab/use-wallet";
|
|
52
|
+
import React from 'react'
|
|
53
|
+
import { reconnectProviders, initializeProviders, WalletProvider } from '@txnlab/use-wallet'
|
|
59
54
|
|
|
60
|
-
const walletProviders = initializeProviders()
|
|
55
|
+
const walletProviders = initializeProviders()
|
|
61
56
|
|
|
62
57
|
export default function App() {
|
|
63
58
|
// Reconnect the session when the user returns to the dApp
|
|
64
59
|
React.useEffect(() => {
|
|
65
|
-
reconnectProviders(walletProviders)
|
|
66
|
-
}, [])
|
|
60
|
+
reconnectProviders(walletProviders)
|
|
61
|
+
}, [])
|
|
67
62
|
|
|
68
|
-
return
|
|
69
|
-
<WalletProvider value={walletProviders}>
|
|
70
|
-
...
|
|
71
|
-
</WalletProvider>);
|
|
63
|
+
return <WalletProvider value={walletProviders}>...</WalletProvider>
|
|
72
64
|
}
|
|
73
65
|
```
|
|
74
66
|
|
|
@@ -77,26 +69,23 @@ The `reconnectProviders` function is used to restore session states of wallets t
|
|
|
77
69
|
By default, all of the supported providers except for `KMD` are returned by `useConnectWallet`. An array can be passed to `initializeProviders` to determine which providers your dApp supports, as shown below.
|
|
78
70
|
|
|
79
71
|
```jsx
|
|
80
|
-
import { initializeProviders, PROVIDER_ID } from
|
|
72
|
+
import { initializeProviders, PROVIDER_ID } from '@txnlab/use-wallet'
|
|
81
73
|
|
|
82
|
-
const walletProviders = initializeProviders([
|
|
83
|
-
PROVIDER_ID.KMD_WALLET,
|
|
84
|
-
PROVIDER_ID.WALLET_CONNECT,
|
|
85
|
-
]);
|
|
74
|
+
const walletProviders = initializeProviders([PROVIDER_ID.KMD_WALLET, PROVIDER_ID.WALLET_CONNECT])
|
|
86
75
|
```
|
|
87
76
|
|
|
88
77
|
For more configuration options, see [Provider Configuration](#provider-configuration).
|
|
89
78
|
|
|
90
79
|
### Connect
|
|
91
80
|
|
|
92
|
-
Map through the `providers` object to list the providers and enable users to connect.
|
|
81
|
+
Map through the `providers` object to list the providers and enable users to connect.
|
|
93
82
|
|
|
94
83
|
```jsx
|
|
95
|
-
import React from
|
|
96
|
-
import { useWallet } from
|
|
84
|
+
import React from 'react'
|
|
85
|
+
import { useWallet } from '@txnlab/use-wallet'
|
|
97
86
|
|
|
98
87
|
export default function Connect() {
|
|
99
|
-
const { providers, activeAccount } = useWallet()
|
|
88
|
+
const { providers, activeAccount } = useWallet()
|
|
100
89
|
|
|
101
90
|
// Map through the providers.
|
|
102
91
|
// Render account information and "connect", "set active", and "disconnect" buttons.
|
|
@@ -104,19 +93,16 @@ export default function Connect() {
|
|
|
104
93
|
return (
|
|
105
94
|
<div>
|
|
106
95
|
{providers?.map((provider) => (
|
|
107
|
-
<div key={
|
|
96
|
+
<div key={'provider-' + provider.metadata.id}>
|
|
108
97
|
<h4>
|
|
109
98
|
<img width={30} height={30} alt="" src={provider.metadata.icon} />
|
|
110
|
-
{provider.metadata.name} {provider.isActive &&
|
|
99
|
+
{provider.metadata.name} {provider.isActive && '[active]'}
|
|
111
100
|
</h4>
|
|
112
101
|
<div>
|
|
113
102
|
<button onClick={provider.connect} disabled={provider.isConnected}>
|
|
114
103
|
Connect
|
|
115
104
|
</button>
|
|
116
|
-
<button
|
|
117
|
-
onClick={provider.disconnect}
|
|
118
|
-
disabled={!provider.isConnected}
|
|
119
|
-
>
|
|
105
|
+
<button onClick={provider.disconnect} disabled={!provider.isConnected}>
|
|
120
106
|
Disconnect
|
|
121
107
|
</button>
|
|
122
108
|
<button
|
|
@@ -132,7 +118,9 @@ export default function Connect() {
|
|
|
132
118
|
onChange={(e) => provider.setActiveAccount(e.target.value)}
|
|
133
119
|
>
|
|
134
120
|
{provider.accounts.map((account) => (
|
|
135
|
-
<option key={account.address} value={account.address}>
|
|
121
|
+
<option key={account.address} value={account.address}>
|
|
122
|
+
{account.address}
|
|
123
|
+
</option>
|
|
136
124
|
))}
|
|
137
125
|
</select>
|
|
138
126
|
)}
|
|
@@ -141,9 +129,8 @@ export default function Connect() {
|
|
|
141
129
|
</div>
|
|
142
130
|
))}
|
|
143
131
|
</div>
|
|
144
|
-
)
|
|
132
|
+
)
|
|
145
133
|
}
|
|
146
|
-
|
|
147
134
|
```
|
|
148
135
|
|
|
149
136
|
Each provider has two connection states: `isConnected` and `isActive`.
|
|
@@ -159,58 +146,47 @@ The `activeAccount` is the primary account that is currently active and will be
|
|
|
159
146
|
Construct a transaction using `algosdk`, and sign and send the transaction using the `signTransactions` and `sendTransactions` functions provided by the `useWallet` hook.
|
|
160
147
|
|
|
161
148
|
```jsx
|
|
162
|
-
import React from
|
|
149
|
+
import React from 'react'
|
|
163
150
|
import {
|
|
164
151
|
useWallet,
|
|
165
152
|
DEFAULT_NODE_BASEURL,
|
|
166
153
|
DEFAULT_NODE_TOKEN,
|
|
167
|
-
DEFAULT_NODE_PORT,
|
|
168
|
-
} from "@txnlab/use-wallet";
|
|
169
|
-
import algosdk from "algosdk";
|
|
170
|
-
|
|
171
|
-
const algodClient = new algosdk.Algodv2(
|
|
172
|
-
DEFAULT_NODE_TOKEN,
|
|
173
|
-
DEFAULT_NODE_BASEURL,
|
|
174
154
|
DEFAULT_NODE_PORT
|
|
175
|
-
|
|
155
|
+
} from '@txnlab/use-wallet'
|
|
156
|
+
import algosdk from 'algosdk'
|
|
157
|
+
|
|
158
|
+
const algodClient = new algosdk.Algodv2(DEFAULT_NODE_TOKEN, DEFAULT_NODE_BASEURL, DEFAULT_NODE_PORT)
|
|
176
159
|
|
|
177
160
|
export default function Transact() {
|
|
178
|
-
const { activeAddress, signTransactions, sendTransactions } = useWallet()
|
|
161
|
+
const { activeAddress, signTransactions, sendTransactions } = useWallet()
|
|
179
162
|
|
|
180
|
-
const sendTransaction = async (
|
|
181
|
-
from?: string,
|
|
182
|
-
to?: string,
|
|
183
|
-
amount?: number
|
|
184
|
-
) => {
|
|
163
|
+
const sendTransaction = async (from?: string, to?: string, amount?: number) => {
|
|
185
164
|
if (!from || !to || !amount) {
|
|
186
|
-
throw new Error(
|
|
165
|
+
throw new Error('Missing transaction params.')
|
|
187
166
|
}
|
|
188
167
|
|
|
189
|
-
const suggestedParams = await algodClient.getTransactionParams().do()
|
|
168
|
+
const suggestedParams = await algodClient.getTransactionParams().do()
|
|
190
169
|
|
|
191
170
|
const transaction = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
|
|
192
171
|
from,
|
|
193
172
|
to,
|
|
194
173
|
amount,
|
|
195
|
-
suggestedParams
|
|
196
|
-
})
|
|
174
|
+
suggestedParams
|
|
175
|
+
})
|
|
197
176
|
|
|
198
|
-
const encodedTransaction = algosdk.encodeUnsignedTransaction(transaction)
|
|
177
|
+
const encodedTransaction = algosdk.encodeUnsignedTransaction(transaction)
|
|
199
178
|
|
|
200
|
-
const signedTransactions = await signTransactions([encodedTransaction])
|
|
179
|
+
const signedTransactions = await signTransactions([encodedTransaction])
|
|
201
180
|
|
|
202
|
-
const waitRoundsToConfirm = 4
|
|
181
|
+
const waitRoundsToConfirm = 4
|
|
203
182
|
|
|
204
|
-
const { id } = await sendTransactions(
|
|
205
|
-
signedTransactions,
|
|
206
|
-
waitRoundsToConfirm
|
|
207
|
-
);
|
|
183
|
+
const { id } = await sendTransactions(signedTransactions, waitRoundsToConfirm)
|
|
208
184
|
|
|
209
|
-
console.log(
|
|
210
|
-
}
|
|
185
|
+
console.log('Successfully sent transaction. Transaction ID: ', id)
|
|
186
|
+
}
|
|
211
187
|
|
|
212
188
|
if (!activeAddress) {
|
|
213
|
-
return <p>Connect an account first.</p
|
|
189
|
+
return <p>Connect an account first.</p>
|
|
214
190
|
}
|
|
215
191
|
|
|
216
192
|
return (
|
|
@@ -222,7 +198,7 @@ export default function Transact() {
|
|
|
222
198
|
Sign and send transactions
|
|
223
199
|
</button>
|
|
224
200
|
</div>
|
|
225
|
-
)
|
|
201
|
+
)
|
|
226
202
|
}
|
|
227
203
|
```
|
|
228
204
|
|
|
@@ -231,14 +207,14 @@ export default function Transact() {
|
|
|
231
207
|
The `activeAccount` object can be used to display details for the currently active account. For convenience, the `activeAddress` property shows the currently active address.
|
|
232
208
|
|
|
233
209
|
```jsx
|
|
234
|
-
import React from
|
|
235
|
-
import { useWallet } from
|
|
210
|
+
import React from 'react'
|
|
211
|
+
import { useWallet } from '@txnlab/use-wallet'
|
|
236
212
|
|
|
237
213
|
export default function Account() {
|
|
238
|
-
const { activeAccount } = useWallet()
|
|
214
|
+
const { activeAccount } = useWallet()
|
|
239
215
|
|
|
240
216
|
if (!activeAccount) {
|
|
241
|
-
return <p>No account active.</p
|
|
217
|
+
return <p>No account active.</p>
|
|
242
218
|
}
|
|
243
219
|
|
|
244
220
|
return (
|
|
@@ -254,7 +230,7 @@ export default function Account() {
|
|
|
254
230
|
Provider: <span>{activeAccount.providerId}</span>
|
|
255
231
|
</p>
|
|
256
232
|
</div>
|
|
257
|
-
)
|
|
233
|
+
)
|
|
258
234
|
}
|
|
259
235
|
```
|
|
260
236
|
|
|
@@ -263,32 +239,30 @@ export default function Account() {
|
|
|
263
239
|
The `isActive` and `isReady` properties can be used to check the status of the wallets. The `isActive` property determines whether or not an account is currently active. The `isReady` property shows if `use-wallet` has mounted and successfully read the connection status from the providers. These properties are useful when setting up client side access restrictions, for example, by redirecting a user if no wallet is active, as shown below.
|
|
264
240
|
|
|
265
241
|
```jsx
|
|
266
|
-
|
|
242
|
+
const { isActive, isReady } = useWallet()
|
|
267
243
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
if (isReady && !isActive) {
|
|
274
|
-
denyAccess()
|
|
275
|
-
}
|
|
276
|
-
})
|
|
244
|
+
useEffect(() => {
|
|
245
|
+
if (isReady && isActive) {
|
|
246
|
+
allowAccess()
|
|
247
|
+
}
|
|
277
248
|
|
|
249
|
+
if (isReady && !isActive) {
|
|
250
|
+
denyAccess()
|
|
251
|
+
}
|
|
252
|
+
})
|
|
278
253
|
```
|
|
279
254
|
|
|
280
|
-
|
|
281
255
|
## Provider Configuration
|
|
282
256
|
|
|
283
257
|
The `initializeProviders` functon accepts a configuration object that can be used to configure the nodes that the providers use to send transactions, as shown below.
|
|
284
258
|
|
|
285
259
|
```jsx
|
|
286
260
|
const walletProviders = initializeProviders([], {
|
|
287
|
-
network:
|
|
288
|
-
nodeServer:
|
|
289
|
-
nodeToken:
|
|
290
|
-
nodePort:
|
|
291
|
-
})
|
|
261
|
+
network: 'devmodenet',
|
|
262
|
+
nodeServer: 'http://algod',
|
|
263
|
+
nodeToken: 'xxxxxxxxx',
|
|
264
|
+
nodePort: '8080'
|
|
265
|
+
})
|
|
292
266
|
```
|
|
293
267
|
|
|
294
268
|
Passing an empty array as the first argument enables all of the default providers. The `network` property should be specified as `betanet`, `testnet`, `mainnet` or the name of your local development network.
|
|
@@ -317,7 +291,7 @@ const walletProviders = {
|
|
|
317
291
|
}),
|
|
318
292
|
};
|
|
319
293
|
|
|
320
|
-
...
|
|
294
|
+
...
|
|
321
295
|
|
|
322
296
|
<WalletProvider value={walletProviders}>
|
|
323
297
|
...
|
|
@@ -326,9 +300,9 @@ const walletProviders = {
|
|
|
326
300
|
|
|
327
301
|
## Static Imports
|
|
328
302
|
|
|
329
|
-
By default, `use-wallet` dynamically imports all of the dependencies for the providiers, as well as `algosdk`, to reduce bundle size.
|
|
303
|
+
By default, `use-wallet` dynamically imports all of the dependencies for the providiers, as well as `algosdk`, to reduce bundle size.
|
|
330
304
|
|
|
331
|
-
Some React frameworks, like [Remix](https://remix.run/), do not support dynamic imports. To get around this, those dependencies can be imported in your application and passed to the `useWallet` provider. See below for an example.
|
|
305
|
+
Some React frameworks, like [Remix](https://remix.run/), do not support dynamic imports. To get around this, those dependencies can be imported in your application and passed to the `useWallet` provider. See below for an example.
|
|
332
306
|
|
|
333
307
|
```jsx
|
|
334
308
|
...
|
|
@@ -412,19 +386,22 @@ yarn link
|
|
|
412
386
|
```
|
|
413
387
|
|
|
414
388
|
In the root of your application, run:
|
|
389
|
+
|
|
415
390
|
```bash
|
|
416
391
|
yarn link @txnlab/use-wallet
|
|
417
392
|
```
|
|
418
393
|
|
|
419
|
-
### Symlink React
|
|
394
|
+
### Symlink React
|
|
420
395
|
|
|
421
396
|
In the root of your application, run:
|
|
397
|
+
|
|
422
398
|
```bash
|
|
423
399
|
cd node_modules/react
|
|
424
400
|
yarn link
|
|
425
401
|
```
|
|
426
402
|
|
|
427
403
|
In the root of `use-wallet` directory, run:
|
|
404
|
+
|
|
428
405
|
```bash
|
|
429
406
|
yarn link react
|
|
430
407
|
```
|
|
@@ -433,8 +410,8 @@ yarn link react
|
|
|
433
410
|
|
|
434
411
|
Are you using `@txnlab/use-wallet`? We'd love to include you here. Let us know! [Twitter](https://twitter.com/NFDomains) | [Discord](https://discord.gg/7XcuMTfeZP) | [Email](mailto:admin@txnlab.dev)
|
|
435
412
|
|
|
436
|
-
|
|
437
|
-
|
|
413
|
+
- [@algoscan/use-wallet-ui](https://github.com/algoscan/use-wallet-ui)
|
|
414
|
+
- [@algoworldnft/algoworld-swapper](https://github.com/algoworldnft/algoworld-swapper)
|
|
438
415
|
|
|
439
416
|
## License
|
|
440
417
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type _algosdk from
|
|
2
|
-
import type { AlgodClientOptions } from
|
|
1
|
+
import type _algosdk from 'algosdk';
|
|
2
|
+
import type { AlgodClientOptions } from '../types';
|
|
3
3
|
export declare const getAlgosdk: () => Promise<typeof _algosdk>;
|
|
4
|
-
export declare const getAlgodClient: (algosdk: typeof _algosdk, algodClientOptions?: AlgodClientOptions) =>
|
|
4
|
+
export declare const getAlgodClient: (algosdk: typeof _algosdk, algodClientOptions?: AlgodClientOptions) => _algosdk.Algodv2;
|
|
5
5
|
export default class Algod {
|
|
6
6
|
algosdk: typeof _algosdk;
|
|
7
7
|
algodClient: _algosdk.Algodv2;
|
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import BaseWallet from
|
|
2
|
-
import { PROVIDER_ID } from
|
|
3
|
-
import type { Network } from
|
|
4
|
-
import type { AlgoSignerClientConstructor, InitParams } from
|
|
1
|
+
import BaseWallet from '../base';
|
|
2
|
+
import { PROVIDER_ID } from '../../constants';
|
|
3
|
+
import type { Network } from '../../types';
|
|
4
|
+
import type { AlgoSignerClientConstructor, InitParams } from './types';
|
|
5
|
+
import { useWalletStore } from '../../store';
|
|
5
6
|
declare class AlgoSignerClient extends BaseWallet {
|
|
6
7
|
#private;
|
|
7
8
|
network: Network;
|
|
8
|
-
|
|
9
|
+
walletStore: typeof useWalletStore;
|
|
10
|
+
constructor({ metadata, client, algosdk, algodClient, network }: AlgoSignerClientConstructor);
|
|
9
11
|
static metadata: {
|
|
10
12
|
id: PROVIDER_ID;
|
|
11
13
|
name: string;
|
|
12
14
|
icon: string;
|
|
13
15
|
isWalletConnect: boolean;
|
|
14
16
|
};
|
|
15
|
-
static init({ algodOptions, algosdkStatic, network
|
|
17
|
+
static init({ algodOptions, algosdkStatic, network }: InitParams): Promise<AlgoSignerClient | null>;
|
|
16
18
|
connect(): Promise<{
|
|
17
19
|
accounts: {
|
|
20
|
+
authAddr?: string | undefined;
|
|
18
21
|
name: string;
|
|
19
22
|
address: string;
|
|
20
23
|
providerId: PROVIDER_ID;
|
|
@@ -27,5 +30,7 @@ declare class AlgoSignerClient extends BaseWallet {
|
|
|
27
30
|
reconnect(onDisconnect: () => void): Promise<null>;
|
|
28
31
|
disconnect(): Promise<void>;
|
|
29
32
|
signTransactions(connectedAccounts: string[], transactions: Uint8Array[], indexesToSign?: number[], returnGroup?: boolean): Promise<Uint8Array[]>;
|
|
33
|
+
getGenesisID(): string;
|
|
34
|
+
getAuthAddress(address: string): string | undefined;
|
|
30
35
|
}
|
|
31
36
|
export default AlgoSignerClient;
|
|
@@ -1,26 +1,30 @@
|
|
|
1
|
-
import type _algosdk from
|
|
2
|
-
import { PROVIDER_ID } from
|
|
3
|
-
import type { AlgodClientOptions, Network, Metadata } from
|
|
1
|
+
import type _algosdk from 'algosdk';
|
|
2
|
+
import { PROVIDER_ID } from '../../constants';
|
|
3
|
+
import type { AlgodClientOptions, Network, Metadata } from '../../types';
|
|
4
4
|
export declare type WindowExtended = {
|
|
5
|
-
|
|
5
|
+
algorand: AlgoSigner;
|
|
6
6
|
} & Window & typeof globalThis;
|
|
7
|
+
export declare type GenesisId = 'betanet-v1.0' | 'testnet-v1.0' | 'mainnet-v1.0' | string;
|
|
8
|
+
export declare type EnableParams = {
|
|
9
|
+
genesisID?: GenesisId;
|
|
10
|
+
genesisHash?: string;
|
|
11
|
+
accounts?: string[];
|
|
12
|
+
};
|
|
13
|
+
export declare type EnableResponse = {
|
|
14
|
+
genesisID: GenesisId;
|
|
15
|
+
genesisHash: string;
|
|
16
|
+
accounts: string[];
|
|
17
|
+
};
|
|
7
18
|
export declare type AlgoSignerTransaction = {
|
|
8
19
|
txn: string;
|
|
9
|
-
signers?: [];
|
|
20
|
+
signers?: string[];
|
|
21
|
+
stxn?: string;
|
|
10
22
|
multisig?: string;
|
|
23
|
+
authAddr?: string;
|
|
11
24
|
};
|
|
12
|
-
export declare type SupportedLedgers = "MainNet" | "TestNet" | "BetaNet" | string;
|
|
13
25
|
export declare type AlgoSigner = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
ledger: SupportedLedgers;
|
|
17
|
-
}) => Promise<{
|
|
18
|
-
address: string;
|
|
19
|
-
}[]>;
|
|
20
|
-
signTxn: (transactions: AlgoSignerTransaction[]) => Promise<{
|
|
21
|
-
txID: string;
|
|
22
|
-
blob: string;
|
|
23
|
-
}[]>;
|
|
26
|
+
enable: (params?: EnableParams) => Promise<EnableResponse>;
|
|
27
|
+
signTxns: (transactions: AlgoSignerTransaction[]) => Promise<string[]>;
|
|
24
28
|
encoding: {
|
|
25
29
|
msgpackToBase64(transaction: Uint8Array): string;
|
|
26
30
|
byteArrayToString(transaction: Uint8Array): string;
|
|
@@ -32,7 +36,7 @@ export declare type AlgoSignerClientConstructor = {
|
|
|
32
36
|
id: PROVIDER_ID;
|
|
33
37
|
algosdk: typeof _algosdk;
|
|
34
38
|
algodClient: _algosdk.Algodv2;
|
|
35
|
-
network:
|
|
39
|
+
network: Network;
|
|
36
40
|
};
|
|
37
41
|
export declare type InitParams = {
|
|
38
42
|
algodOptions?: AlgodClientOptions;
|
package/dist/cjs/index.js
CHANGED
|
@@ -23,8 +23,8 @@ const DEFAULT_NODE_PORT = "";
|
|
|
23
23
|
const getAlgosdk = async () => {
|
|
24
24
|
return (await import('algosdk')).default;
|
|
25
25
|
};
|
|
26
|
-
const getAlgodClient =
|
|
27
|
-
const [tokenOrBaseClient = DEFAULT_NODE_TOKEN, baseServer = DEFAULT_NODE_BASEURL, port = DEFAULT_NODE_PORT, headers
|
|
26
|
+
const getAlgodClient = (algosdk, algodClientOptions) => {
|
|
27
|
+
const [tokenOrBaseClient = DEFAULT_NODE_TOKEN, baseServer = DEFAULT_NODE_BASEURL, port = DEFAULT_NODE_PORT, headers] = algodClientOptions || [];
|
|
28
28
|
return new algosdk.Algodv2(tokenOrBaseClient, baseServer, port, headers);
|
|
29
29
|
};
|
|
30
30
|
class Algod {
|
|
@@ -1576,81 +1576,75 @@ class ExodusClient extends BaseClient {
|
|
|
1576
1576
|
const ICON$3 = "data:image/svg+xml;base64," +
|
|
1577
1577
|
"PHN2ZyB3aWR0aD0iMjM4IiBoZWlnaHQ9IjIzOCIgdmlld0JveD0iMCAwIDIzOCAyMzgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik01MS43MDUgMTQ1LjA0MkgxMTYuNzA1TDEwNy43MDUgMTU1LjA0Mkg1MS43MDVWMTQ1LjA0MloiIGZpbGw9IiNENjQ1MDAiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNDcuNTE5IDE5MS41NTdMMTI5LjU3NyAxNDQuMzk0TDE0Mi40MDQgMTI3LjExMkwxNjcuODc1IDE5MS41NTdIMTQ3LjUxOVpNMTEwLjkzNiA5NS4zOTMyTDEyMC42MTMgMTIwLjgzMUwxMzMuMzU5IDEwNC4yMjhMMTE3LjQ3NSA2NC4wNDIyQzExNS45MjggNjAuMTI4IDExMi4xNDYgNTcuNTU2NSAxMDcuOTM4IDU3LjU1NjVDMTAzLjcyOSA1Ny41NTY1IDk5Ljk0NzQgNjAuMTI4IDk4LjQwMDMgNjQuMDQyMkw2Ny45NjU5IDE0MS4wNDJIODcuNzgwN0M5NS40MTUzIDEyMS4wMTEgMTAyLjg5MyAxMDEuMzk5IDEwNS4xOTggOTUuMzU0MUMxMDUuNjQxIDk0LjE5MTIgMTA2Ljc0MyA5My40NTk5IDEwNy45ODcgOTMuNDU5OUgxMDguMTMyQzEwOS4zNzggOTMuNDU5OSAxMTAuNDkzIDk0LjIyOTMgMTEwLjkzNiA5NS4zOTMyWk04MC45MjEgMTU5LjA0MkM3NC45Mjg5IDE3NC43NjggNjkuODY2MSAxODguMDYzIDY4LjU0NDcgMTkxLjU1N0g0OEw2MC44NTE0IDE1OS4wNDJIODAuOTIxWiIgZmlsbD0iIzIyMkI2MCIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTE3Ni4wMjYgNTQuNzUwOUMxNzcuOTk3IDUyLjA4NzIgMTgxLjc1NCA1MS41MjU3IDE4NC40MTggNTMuNDk2N0MxODcuMDgyIDU1LjQ2NzggMTg3LjY0MyA1OS4yMjUxIDE4NS42NzIgNjEuODg4OEwxMzAuMDEzIDEzNy4xMDdDMTI5LjcxNCAxMzcuNTEyIDEyOS4zNDEgMTM3Ljg1NyAxMjguOTEzIDEzOC4xMjNMMTE3Ljg1NiAxNDUuMDEzQzExNy4wODcgMTQ1LjQ5MyAxMTYuMTI4IDE0NC43ODMgMTE2LjM2MSAxNDMuOTA3TDExOS43MTggMTMxLjMxOEMxMTkuODQ3IDEzMC44MzIgMTIwLjA2OCAxMzAuMzc0IDEyMC4zNjcgMTI5Ljk3TDE3MC42NyA2MS45ODlMMTY5LjkyOSA2MS40NDA1QzE2OS40ODUgNjEuMTEyIDE2OC44NTkgNjEuMjA1NiAxNjguNTMgNjEuNjQ5NkwxNTIuMzExIDgzLjU2ODhDMTUyLjU4NiA4NC4yMDIzIDE1Mi41MjQgODQuOTYxMiAxNTIuMDg0IDg1LjU1NjJMMTQ5LjExIDg5LjU3NTVDMTQ4LjQ1MyA5MC40NjM0IDE0Ny4yMDEgOTAuNjUwNiAxNDYuMzEzIDg5Ljk5MzZDMTQ1LjQyNSA4OS4zMzY2IDE0NS4yMzggODguMDg0MSAxNDUuODk1IDg3LjE5NjJMMTQ3LjY3OSA4NC43ODQ3TDE0OC44NjkgODMuMTc2OUwxNjcuMzA4IDU4LjI1NzRDMTY4LjYyMiA1Ni40ODE1IDE3MS4xMjcgNTYuMTA3MiAxNzIuOTAzIDU3LjQyMTJMMTczLjY0NCA1Ny45Njk3TDE3Ni4wMjYgNTQuNzUwOVoiIGZpbGw9IiNENjQ1MDAiLz4KPC9zdmc+Cg==";
|
|
1578
1578
|
|
|
1579
|
-
const getNetwork = (network) => {
|
|
1580
|
-
if (network === "betanet") {
|
|
1581
|
-
return "BetaNet";
|
|
1582
|
-
}
|
|
1583
|
-
if (network === "testnet") {
|
|
1584
|
-
return "TestNet";
|
|
1585
|
-
}
|
|
1586
|
-
if (network === "mainnet") {
|
|
1587
|
-
return "MainNet";
|
|
1588
|
-
}
|
|
1589
|
-
return network;
|
|
1590
|
-
};
|
|
1591
1579
|
class AlgoSignerClient extends BaseClient {
|
|
1592
1580
|
#client;
|
|
1593
1581
|
network;
|
|
1594
|
-
|
|
1582
|
+
walletStore;
|
|
1583
|
+
constructor({ metadata, client, algosdk, algodClient, network }) {
|
|
1595
1584
|
super(metadata, algosdk, algodClient);
|
|
1596
1585
|
this.#client = client;
|
|
1597
1586
|
this.network = network;
|
|
1587
|
+
this.walletStore = useWalletStore;
|
|
1598
1588
|
}
|
|
1599
1589
|
static metadata = {
|
|
1600
1590
|
id: exports.PROVIDER_ID.ALGOSIGNER,
|
|
1601
|
-
name:
|
|
1591
|
+
name: 'AlgoSigner',
|
|
1602
1592
|
icon: ICON$3,
|
|
1603
|
-
isWalletConnect: false
|
|
1593
|
+
isWalletConnect: false
|
|
1604
1594
|
};
|
|
1605
|
-
static async init({ algodOptions, algosdkStatic, network = DEFAULT_NETWORK$1
|
|
1595
|
+
static async init({ algodOptions, algosdkStatic, network = DEFAULT_NETWORK$1 }) {
|
|
1606
1596
|
try {
|
|
1607
|
-
if (typeof window ==
|
|
1608
|
-
|
|
1609
|
-
throw new Error("AlgoSigner is not available.");
|
|
1597
|
+
if (typeof window == 'undefined' || window.algorand === undefined) {
|
|
1598
|
+
throw new Error('AlgoSigner is not available.');
|
|
1610
1599
|
}
|
|
1611
1600
|
const algosdk = algosdkStatic || (await Algod.init(algodOptions)).algosdk;
|
|
1612
|
-
const algodClient =
|
|
1613
|
-
const algosigner = window.
|
|
1601
|
+
const algodClient = getAlgodClient(algosdk, algodOptions);
|
|
1602
|
+
const algosigner = window.algorand;
|
|
1614
1603
|
return new AlgoSignerClient({
|
|
1615
1604
|
metadata: AlgoSignerClient.metadata,
|
|
1616
1605
|
id: exports.PROVIDER_ID.ALGOSIGNER,
|
|
1617
1606
|
client: algosigner,
|
|
1618
1607
|
algosdk: algosdk,
|
|
1619
1608
|
algodClient: algodClient,
|
|
1620
|
-
network
|
|
1609
|
+
network
|
|
1621
1610
|
});
|
|
1622
1611
|
}
|
|
1623
1612
|
catch (e) {
|
|
1624
1613
|
console.warn(e);
|
|
1625
|
-
console.warn(`Error initializing ${AlgoSignerClient.metadata.name}.`,
|
|
1614
|
+
console.warn(`Error initializing ${AlgoSignerClient.metadata.name}.`, 'Do you have the extension installed?', 'https://www.purestake.com/technology/algosigner');
|
|
1626
1615
|
return null;
|
|
1627
1616
|
}
|
|
1628
1617
|
}
|
|
1629
1618
|
async connect() {
|
|
1630
|
-
await this.#client.
|
|
1631
|
-
const accounts = await this.#client.accounts({
|
|
1632
|
-
ledger: getNetwork(this.network),
|
|
1633
|
-
});
|
|
1619
|
+
const { accounts } = await this.#client.enable({ genesisID: this.getGenesisID() });
|
|
1634
1620
|
if (accounts.length === 0) {
|
|
1635
1621
|
throw new Error(`No accounts found for ${AlgoSignerClient.metadata.id}`);
|
|
1636
1622
|
}
|
|
1637
|
-
const mappedAccounts = accounts.map((
|
|
1638
|
-
|
|
1639
|
-
address
|
|
1640
|
-
|
|
1623
|
+
const mappedAccounts = await Promise.all(accounts.map(async (address, index) => {
|
|
1624
|
+
// check to see if this is a rekeyed account
|
|
1625
|
+
const { 'auth-addr': authAddr } = await this.getAccountInfo(address);
|
|
1626
|
+
return {
|
|
1627
|
+
name: `AlgoSigner ${index + 1}`,
|
|
1628
|
+
address,
|
|
1629
|
+
providerId: AlgoSignerClient.metadata.id,
|
|
1630
|
+
...(authAddr && { authAddr })
|
|
1631
|
+
};
|
|
1641
1632
|
}));
|
|
1633
|
+
// sort the accounts in the order they were returned by AlgoSigner
|
|
1634
|
+
mappedAccounts.sort((a, b) => accounts.indexOf(a.address) - accounts.indexOf(b.address));
|
|
1642
1635
|
return {
|
|
1643
1636
|
...AlgoSignerClient.metadata,
|
|
1644
|
-
accounts: mappedAccounts
|
|
1637
|
+
accounts: mappedAccounts
|
|
1645
1638
|
};
|
|
1646
1639
|
}
|
|
1640
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
1647
1641
|
async reconnect(onDisconnect) {
|
|
1648
|
-
if (window === undefined ||
|
|
1649
|
-
window.AlgoSigner === undefined) {
|
|
1642
|
+
if (window === undefined || window.algorand === undefined) {
|
|
1650
1643
|
onDisconnect();
|
|
1651
1644
|
}
|
|
1652
1645
|
return null;
|
|
1653
1646
|
}
|
|
1647
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
1654
1648
|
async disconnect() {
|
|
1655
1649
|
return;
|
|
1656
1650
|
}
|
|
@@ -1659,49 +1653,70 @@ class AlgoSignerClient extends BaseClient {
|
|
|
1659
1653
|
const decodedTxns = transactions.map((txn) => {
|
|
1660
1654
|
return this.algosdk.decodeObj(txn);
|
|
1661
1655
|
});
|
|
1656
|
+
const signedIndexes = [];
|
|
1662
1657
|
// Marshal the transactions,
|
|
1663
1658
|
// and add the signers property if they shouldn't be signed.
|
|
1664
1659
|
const txnsToSign = decodedTxns.reduce((acc, txn, i) => {
|
|
1665
|
-
const isSigned =
|
|
1666
|
-
const
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1660
|
+
const isSigned = 'txn' in txn;
|
|
1661
|
+
const sender = this.algosdk.encodeAddress(isSigned ? txn.txn.snd : txn.snd);
|
|
1662
|
+
const authAddress = this.getAuthAddress(sender); // rekeyed-to account, or undefined
|
|
1663
|
+
if (indexesToSign && indexesToSign.length && indexesToSign.includes(i)) {
|
|
1664
|
+
signedIndexes.push(i);
|
|
1665
|
+
acc.push({
|
|
1666
|
+
txn: this.#client.encoding.msgpackToBase64(transactions[i]),
|
|
1667
|
+
...(authAddress && { authAddr: authAddress })
|
|
1668
|
+
});
|
|
1669
|
+
}
|
|
1670
|
+
else if (!isSigned && connectedAccounts.includes(sender)) {
|
|
1671
|
+
signedIndexes.push(i);
|
|
1672
|
+
acc.push({
|
|
1673
|
+
txn: this.#client.encoding.msgpackToBase64(transactions[i]),
|
|
1674
|
+
...(authAddress && { authAddr: authAddress })
|
|
1675
|
+
});
|
|
1678
1676
|
}
|
|
1679
|
-
else
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
.decodeSignedTransaction(transactions[i])
|
|
1683
|
-
.
|
|
1684
|
-
:
|
|
1685
|
-
|
|
1677
|
+
else {
|
|
1678
|
+
acc.push({
|
|
1679
|
+
txn: this.#client.encoding.msgpackToBase64(isSigned
|
|
1680
|
+
? this.algosdk.decodeSignedTransaction(transactions[i]).txn.toByte()
|
|
1681
|
+
: this.algosdk.decodeUnsignedTransaction(transactions[i]).toByte()),
|
|
1682
|
+
signers: []
|
|
1683
|
+
});
|
|
1686
1684
|
}
|
|
1687
|
-
acc.push(txnObj);
|
|
1688
1685
|
return acc;
|
|
1689
1686
|
}, []);
|
|
1690
1687
|
// Sign them with the client.
|
|
1691
|
-
const result = await this.#client.
|
|
1688
|
+
const result = await this.#client.signTxns(txnsToSign);
|
|
1692
1689
|
// Join the newly signed transactions with the original group of transactions
|
|
1693
|
-
// if
|
|
1694
|
-
const signedTxns =
|
|
1695
|
-
if (
|
|
1696
|
-
|
|
1690
|
+
// if `returnGroup` is true
|
|
1691
|
+
const signedTxns = transactions.reduce((acc, txn, i) => {
|
|
1692
|
+
if (signedIndexes.includes(i)) {
|
|
1693
|
+
const signedByUser = result[i];
|
|
1694
|
+
signedByUser && acc.push(new Uint8Array(Buffer.from(signedByUser, 'base64')));
|
|
1697
1695
|
}
|
|
1698
1696
|
else if (returnGroup) {
|
|
1699
|
-
acc.push(
|
|
1697
|
+
acc.push(txn);
|
|
1700
1698
|
}
|
|
1701
1699
|
return acc;
|
|
1702
1700
|
}, []);
|
|
1703
1701
|
return signedTxns;
|
|
1704
1702
|
}
|
|
1703
|
+
getGenesisID() {
|
|
1704
|
+
if (this.network === 'betanet') {
|
|
1705
|
+
return 'betanet-v1.0';
|
|
1706
|
+
}
|
|
1707
|
+
if (this.network === 'testnet') {
|
|
1708
|
+
return 'testnet-v1.0';
|
|
1709
|
+
}
|
|
1710
|
+
if (this.network === 'mainnet') {
|
|
1711
|
+
return 'mainnet-v1.0';
|
|
1712
|
+
}
|
|
1713
|
+
return this.network;
|
|
1714
|
+
}
|
|
1715
|
+
getAuthAddress(address) {
|
|
1716
|
+
const accounts = this.walletStore.getState().accounts;
|
|
1717
|
+
const account = accounts.find((acct) => acct.address === address && acct.providerId === this.metadata.id);
|
|
1718
|
+
return account?.authAddr;
|
|
1719
|
+
}
|
|
1705
1720
|
}
|
|
1706
1721
|
|
|
1707
1722
|
const ICON$2 = "data:image/svg+xml;base64," +
|
|
@@ -1860,10 +1875,12 @@ class WalletConnectClient extends BaseClient {
|
|
|
1860
1875
|
// Sign them with the client.
|
|
1861
1876
|
const result = await this.#client.sendCustomRequest(request);
|
|
1862
1877
|
this.keepWCAliveStop();
|
|
1878
|
+
// Check if the result is the same length as the transactions
|
|
1879
|
+
const lengthsMatch = result.length === transactions.length;
|
|
1863
1880
|
// Join the newly signed transactions with the original group of transactions.
|
|
1864
1881
|
const signedTxns = transactions.reduce((acc, txn, i) => {
|
|
1865
1882
|
if (signedIndexes.includes(i)) {
|
|
1866
|
-
const signedByUser = result[i];
|
|
1883
|
+
const signedByUser = lengthsMatch ? result[i] : result.shift();
|
|
1867
1884
|
signedByUser && acc.push(new Uint8Array(Buffer.from(signedByUser, 'base64')));
|
|
1868
1885
|
}
|
|
1869
1886
|
else if (returnGroup) {
|