@jaw.id/wagmi 0.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/README.md +147 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/lib/Actions.d.ts +2 -0
- package/dist/lib/Actions.d.ts.map +1 -0
- package/dist/lib/Actions.js +1 -0
- package/dist/lib/Connector.d.ts +30 -0
- package/dist/lib/Connector.d.ts.map +1 -0
- package/dist/lib/Connector.js +254 -0
- package/dist/lib/Connector.test.d.ts +2 -0
- package/dist/lib/Connector.test.d.ts.map +1 -0
- package/dist/lib/Connector.test.js +18 -0
- package/dist/lib/Hooks.d.ts +2 -0
- package/dist/lib/Hooks.d.ts.map +1 -0
- package/dist/lib/Hooks.js +1 -0
- package/dist/lib/Query.d.ts +2 -0
- package/dist/lib/Query.d.ts.map +1 -0
- package/dist/lib/Query.js +1 -0
- package/dist/lib/internal/core.d.ts +264 -0
- package/dist/lib/internal/core.d.ts.map +1 -0
- package/dist/lib/internal/core.js +248 -0
- package/dist/lib/internal/query.d.ts +98 -0
- package/dist/lib/internal/query.d.ts.map +1 -0
- package/dist/lib/internal/query.js +67 -0
- package/dist/lib/internal/react.d.ts +247 -0
- package/dist/lib/internal/react.d.ts.map +1 -0
- package/dist/lib/internal/react.js +517 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# @jaw.id/wagmi
|
|
2
|
+
|
|
3
|
+
Wagmi connector and React hooks for JAW (JustaName Account Wallet) smart accounts.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @jaw.id/wagmi wagmi @tanstack/react-query
|
|
9
|
+
# or
|
|
10
|
+
yarn add @jaw.id/wagmi wagmi @tanstack/react-query
|
|
11
|
+
# or
|
|
12
|
+
bun add @jaw.id/wagmi wagmi @tanstack/react-query
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
### 1. Configure Wagmi with JAW Connector
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { createConfig, http } from 'wagmi';
|
|
21
|
+
import { mainnet, sepolia } from 'wagmi/chains';
|
|
22
|
+
import { jaw } from '@jaw.id/wagmi';
|
|
23
|
+
|
|
24
|
+
export const config = createConfig({
|
|
25
|
+
chains: [mainnet, sepolia],
|
|
26
|
+
connectors: [
|
|
27
|
+
jaw({
|
|
28
|
+
apiKey: 'your-api-key',
|
|
29
|
+
}),
|
|
30
|
+
],
|
|
31
|
+
transports: {
|
|
32
|
+
[mainnet.id]: http(),
|
|
33
|
+
[sepolia.id]: http(),
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2. Use React Hooks
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
import { useConnect, useDisconnect, useGrantPermissions } from '@jaw.id/wagmi';
|
|
42
|
+
import { useAccount } from 'wagmi';
|
|
43
|
+
|
|
44
|
+
function App() {
|
|
45
|
+
const { connect } = useConnect();
|
|
46
|
+
const { disconnect } = useDisconnect();
|
|
47
|
+
const { address, isConnected } = useAccount();
|
|
48
|
+
const { grantPermissions } = useGrantPermissions();
|
|
49
|
+
|
|
50
|
+
if (isConnected) {
|
|
51
|
+
return (
|
|
52
|
+
<div>
|
|
53
|
+
<p>Connected: {address}</p>
|
|
54
|
+
<button onClick={() => disconnect()}>Disconnect</button>
|
|
55
|
+
<button onClick={() => grantPermissions({ permissions: [...] })}>
|
|
56
|
+
Grant Permissions
|
|
57
|
+
</button>
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return <button onClick={() => connect()}>Connect</button>;
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Exports
|
|
67
|
+
|
|
68
|
+
### Connector
|
|
69
|
+
|
|
70
|
+
- `jaw(options)` - Wagmi connector factory
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { jaw } from '@jaw.id/wagmi';
|
|
74
|
+
|
|
75
|
+
const connector = jaw({
|
|
76
|
+
apiKey: 'your-api-key',
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### React Hooks
|
|
81
|
+
|
|
82
|
+
Available as named exports or via the `Hooks` namespace:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { useConnect, Hooks } from '@jaw.id/wagmi';
|
|
86
|
+
|
|
87
|
+
// Both are equivalent:
|
|
88
|
+
useConnect();
|
|
89
|
+
Hooks.useConnect();
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
| Hook | Description |
|
|
93
|
+
|------|-------------|
|
|
94
|
+
| `useConnect` | Connect to JAW wallet |
|
|
95
|
+
| `useDisconnect` | Disconnect from wallet |
|
|
96
|
+
| `useGrantPermissions` | Grant permissions to apps (EIP-7715) |
|
|
97
|
+
| `useRevokePermissions` | Revoke previously granted permissions |
|
|
98
|
+
| `usePermissions` | Query current permissions |
|
|
99
|
+
| `useGetAssets` | Query wallet assets (EIP-7811) |
|
|
100
|
+
| `useCapabilities` | Query wallet capabilities |
|
|
101
|
+
|
|
102
|
+
### Actions (Non-React)
|
|
103
|
+
|
|
104
|
+
For use outside React components or with other state managers:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { connect, Actions } from '@jaw.id/wagmi';
|
|
108
|
+
|
|
109
|
+
// Both are equivalent:
|
|
110
|
+
await connect(config, { connector });
|
|
111
|
+
await Actions.connect(config, { connector });
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
| Action | Description |
|
|
115
|
+
|--------|-------------|
|
|
116
|
+
| `connect` | Connect to wallet |
|
|
117
|
+
| `disconnect` | Disconnect from wallet |
|
|
118
|
+
| `grantPermissions` | Grant permissions |
|
|
119
|
+
| `revokePermissions` | Revoke permissions |
|
|
120
|
+
| `getPermissions` | Get current permissions |
|
|
121
|
+
| `getAssets` | Get wallet assets |
|
|
122
|
+
| `getCapabilities` | Get wallet capabilities |
|
|
123
|
+
|
|
124
|
+
### TanStack Query Utilities
|
|
125
|
+
|
|
126
|
+
Query key factories for custom query implementations:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { Query, getPermissionsQueryKey } from '@jaw.id/wagmi';
|
|
130
|
+
|
|
131
|
+
// Use with TanStack Query
|
|
132
|
+
const queryKey = getPermissionsQueryKey({ address, chainId });
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Peer Dependencies
|
|
136
|
+
|
|
137
|
+
- `react` >= 18.0.0
|
|
138
|
+
- `wagmi` >= 3.0.0
|
|
139
|
+
- `@tanstack/react-query` >= 5.0.0
|
|
140
|
+
|
|
141
|
+
## Documentation
|
|
142
|
+
|
|
143
|
+
For detailed guides, API reference, and examples, visit **[docs.jaw.id](https://docs.jaw.id)**.
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
[MIT](../../LICENSE.md)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { jaw, type JawParameters, type WalletConnectCapabilities, type AccountWithCapabilities, } from './lib/Connector.js';
|
|
2
|
+
export type { PersonalSignRequestData, TypedDataRequestData, PermissionsDetail, CallPermissionDetail, SpendPermissionDetail, } from '@jaw.id/core';
|
|
3
|
+
export * as Actions from './lib/Actions.js';
|
|
4
|
+
export * as Hooks from './lib/Hooks.js';
|
|
5
|
+
export * as Query from './lib/Query.js';
|
|
6
|
+
export { useConnect, useDisconnect, useGrantPermissions, useRevokePermissions, usePermissions, useGetAssets, useCapabilities, useSign, useGetCallsHistory, } from './lib/Hooks.js';
|
|
7
|
+
export { connect, disconnect, grantPermissions, getPermissions, revokePermissions, getAssets, getCapabilities, sign, getCallsHistory, } from './lib/Actions.js';
|
|
8
|
+
export { getPermissionsQueryKey, getAssetsQueryKey, getCapabilitiesQueryKey, getCallsHistoryQueryKey } from './lib/Query.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,GAAG,EACH,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,GAC7B,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EACV,uBAAuB,EACvB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AAGtB,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAG5C,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AAGxC,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AAGxC,OAAO,EACL,UAAU,EACV,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,OAAO,EACP,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,OAAO,EACP,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,eAAe,EACf,IAAI,EACJ,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Connector
|
|
2
|
+
export { jaw, } from './lib/Connector.js';
|
|
3
|
+
// Actions namespace
|
|
4
|
+
export * as Actions from './lib/Actions.js';
|
|
5
|
+
// Hooks namespace
|
|
6
|
+
export * as Hooks from './lib/Hooks.js';
|
|
7
|
+
// Query namespace
|
|
8
|
+
export * as Query from './lib/Query.js';
|
|
9
|
+
// Also export individual hooks for convenience
|
|
10
|
+
export { useConnect, useDisconnect, useGrantPermissions, useRevokePermissions, usePermissions, useGetAssets, useCapabilities, useSign, useGetCallsHistory, } from './lib/Hooks.js';
|
|
11
|
+
// Also export individual actions for convenience
|
|
12
|
+
export { connect, disconnect, grantPermissions, getPermissions, revokePermissions, getAssets, getCapabilities, sign, getCallsHistory, } from './lib/Actions.js';
|
|
13
|
+
// Also export query keys for convenience
|
|
14
|
+
export { getPermissionsQueryKey, getAssetsQueryKey, getCapabilitiesQueryKey, getCallsHistoryQueryKey } from './lib/Query.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Actions.d.ts","sourceRoot":"","sources":["../../src/lib/Actions.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,SAAS,EACT,eAAe,EACf,IAAI,EACJ,eAAe,GAChB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { connect, disconnect, grantPermissions, getPermissions, revokePermissions, getAssets, getCapabilities, sign, getCallsHistory, } from './internal/core.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type CreateJAWSDKOptions, type ProviderInterface, type WalletConnectCapabilities, type WalletConnectResponse } from '@jaw.id/core';
|
|
2
|
+
import { type ProviderConnectInfo } from 'viem';
|
|
3
|
+
export type JawParameters = CreateJAWSDKOptions;
|
|
4
|
+
export type { WalletConnectCapabilities } from '@jaw.id/core';
|
|
5
|
+
type ConnectParameters = {
|
|
6
|
+
chainId?: number | undefined;
|
|
7
|
+
isReconnecting?: boolean | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Capabilities to request during wallet_connect.
|
|
10
|
+
* When provided, uses wallet_connect instead of eth_requestAccounts.
|
|
11
|
+
*/
|
|
12
|
+
capabilities?: WalletConnectCapabilities | undefined;
|
|
13
|
+
};
|
|
14
|
+
/** Account with capabilities returned from wallet_connect */
|
|
15
|
+
export type AccountWithCapabilities = {
|
|
16
|
+
address: `0x${string}`;
|
|
17
|
+
capabilities?: WalletConnectResponse['accounts'][number]['capabilities'];
|
|
18
|
+
};
|
|
19
|
+
type ConnectorProperties = {
|
|
20
|
+
connect(parameters?: ConnectParameters): Promise<{
|
|
21
|
+
accounts: readonly `0x${string}`[] | readonly AccountWithCapabilities[];
|
|
22
|
+
chainId: number;
|
|
23
|
+
}>;
|
|
24
|
+
onConnect(connectInfo: ProviderConnectInfo): void;
|
|
25
|
+
};
|
|
26
|
+
export declare function jaw(parameters: JawParameters): import("@wagmi/core").CreateConnectorFn<ProviderInterface, ConnectorProperties, Record<string, unknown>>;
|
|
27
|
+
export declare namespace jaw {
|
|
28
|
+
var type: "jaw";
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=Connector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Connector.d.ts","sourceRoot":"","sources":["../../src/lib/Connector.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAG3B,MAAM,cAAc,CAAC;AAMtB,OAAO,EAGL,KAAK,mBAAmB,EAIzB,MAAM,MAAM,CAAC;AAGd,MAAM,MAAM,aAAa,GAAG,mBAAmB,CAAC;AAGhD,YAAY,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAwB9D,KAAK,iBAAiB,GAAG;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC;;;OAGG;IACH,YAAY,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;CACtD,CAAC;AAEF,6DAA6D;AAC7D,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,qBAAqB,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;CAC1E,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,OAAO,CAAC,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC;QAC/C,QAAQ,EAAE,SAAS,KAAK,MAAM,EAAE,EAAE,GAAG,SAAS,uBAAuB,EAAE,CAAC;QACxE,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,SAAS,CAAC,WAAW,EAAE,mBAAmB,GAAG,IAAI,CAAC;CACnD,CAAC;AAEF,wBAAgB,GAAG,CAAC,UAAU,EAAE,aAAa,4GAkQ5C;yBAlQe,GAAG"}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { JAW, JAW_WALLET_ICON, } from '@jaw.id/core';
|
|
2
|
+
import { ChainNotConfiguredError, createConnector, } from '@wagmi/core';
|
|
3
|
+
import { getAddress, numberToHex, SwitchChainError, UserRejectedRequestError, withRetry, } from 'viem';
|
|
4
|
+
import { JAW_WALLET_ID, JAW_WALLET_NAME, JAW_WALLET_RDNS } from "@jaw.id/core";
|
|
5
|
+
jaw.type = 'jaw';
|
|
6
|
+
/**
|
|
7
|
+
* Helper to parse accounts from various response formats
|
|
8
|
+
*/
|
|
9
|
+
function parseAccounts(accountsResult) {
|
|
10
|
+
if (Array.isArray(accountsResult)) {
|
|
11
|
+
return accountsResult.map((x) => getAddress(x));
|
|
12
|
+
}
|
|
13
|
+
if (accountsResult && typeof accountsResult === 'object' && 'accounts' in accountsResult) {
|
|
14
|
+
const response = accountsResult;
|
|
15
|
+
if (Array.isArray(response.accounts) && response.accounts.length > 0) {
|
|
16
|
+
const first = response.accounts[0];
|
|
17
|
+
if (typeof first === 'string') {
|
|
18
|
+
return response.accounts.map((x) => getAddress(x));
|
|
19
|
+
}
|
|
20
|
+
return response.accounts.map((acc) => getAddress(acc.address));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
export function jaw(parameters) {
|
|
26
|
+
let sdk;
|
|
27
|
+
let provider_;
|
|
28
|
+
let accountsChanged;
|
|
29
|
+
let chainChanged;
|
|
30
|
+
let connect;
|
|
31
|
+
let disconnect;
|
|
32
|
+
return createConnector((config) => ({
|
|
33
|
+
id: JAW_WALLET_ID,
|
|
34
|
+
name: JAW_WALLET_NAME,
|
|
35
|
+
type: jaw.type,
|
|
36
|
+
rdns: JAW_WALLET_RDNS,
|
|
37
|
+
icon: JAW_WALLET_ICON,
|
|
38
|
+
async setup() {
|
|
39
|
+
// Setup connect listener for auto-reconnection
|
|
40
|
+
if (!connect) {
|
|
41
|
+
const provider = await this.getProvider();
|
|
42
|
+
connect = this.onConnect.bind(this);
|
|
43
|
+
provider.on('connect', connect);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
async connect({ chainId, isReconnecting, capabilities } = {}) {
|
|
47
|
+
const targetChainId = chainId;
|
|
48
|
+
let accounts = [];
|
|
49
|
+
let accountsWithCapabilities = [];
|
|
50
|
+
let currentChainId;
|
|
51
|
+
// Handle reconnection
|
|
52
|
+
if (isReconnecting) {
|
|
53
|
+
[accounts, currentChainId] = await Promise.all([
|
|
54
|
+
this.getAccounts().catch(() => []),
|
|
55
|
+
this.getChainId().catch(() => undefined),
|
|
56
|
+
]);
|
|
57
|
+
if (targetChainId && currentChainId !== targetChainId) {
|
|
58
|
+
const chain = await this.switchChain?.({ chainId: targetChainId }).catch((error) => {
|
|
59
|
+
if (error.code === UserRejectedRequestError.code)
|
|
60
|
+
throw error;
|
|
61
|
+
return { id: currentChainId };
|
|
62
|
+
});
|
|
63
|
+
currentChainId = chain?.id ?? currentChainId;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const provider = await this.getProvider();
|
|
67
|
+
try {
|
|
68
|
+
if (!accounts?.length && !isReconnecting) {
|
|
69
|
+
// Use wallet_connect if capabilities are requested, otherwise use eth_requestAccounts
|
|
70
|
+
if (capabilities && Object.keys(capabilities).length > 0) {
|
|
71
|
+
const walletConnectResponse = await provider.request({
|
|
72
|
+
method: 'wallet_connect',
|
|
73
|
+
params: [{ capabilities }],
|
|
74
|
+
});
|
|
75
|
+
// Extract accounts with their capabilities
|
|
76
|
+
accountsWithCapabilities = walletConnectResponse.accounts.map((acc) => ({
|
|
77
|
+
address: getAddress(acc.address),
|
|
78
|
+
capabilities: acc.capabilities,
|
|
79
|
+
}));
|
|
80
|
+
accounts = accountsWithCapabilities.map((acc) => acc.address);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const accountsResult = await provider.request({
|
|
84
|
+
method: 'eth_requestAccounts',
|
|
85
|
+
});
|
|
86
|
+
accounts = parseAccounts(accountsResult);
|
|
87
|
+
}
|
|
88
|
+
currentChainId = await this.getChainId();
|
|
89
|
+
}
|
|
90
|
+
if (!currentChainId)
|
|
91
|
+
throw new ChainNotConfiguredError();
|
|
92
|
+
// Manage EIP-1193 event listeners
|
|
93
|
+
if (connect) {
|
|
94
|
+
provider.removeListener('connect', connect);
|
|
95
|
+
connect = undefined;
|
|
96
|
+
}
|
|
97
|
+
if (!accountsChanged) {
|
|
98
|
+
accountsChanged = this.onAccountsChanged.bind(this);
|
|
99
|
+
provider.on('accountsChanged', accountsChanged);
|
|
100
|
+
}
|
|
101
|
+
if (!chainChanged) {
|
|
102
|
+
chainChanged = this.onChainChanged.bind(this);
|
|
103
|
+
provider.on('chainChanged', chainChanged);
|
|
104
|
+
}
|
|
105
|
+
if (!disconnect) {
|
|
106
|
+
disconnect = this.onDisconnect.bind(this);
|
|
107
|
+
provider.on('disconnect', disconnect);
|
|
108
|
+
}
|
|
109
|
+
// Switch chain if requested and different from current (skip if handled during reconnection)
|
|
110
|
+
if (targetChainId && currentChainId !== targetChainId && !isReconnecting) {
|
|
111
|
+
const chain = await this.switchChain?.({ chainId: targetChainId }).catch((error) => {
|
|
112
|
+
if (error.code === UserRejectedRequestError.code)
|
|
113
|
+
throw error;
|
|
114
|
+
return { id: currentChainId };
|
|
115
|
+
});
|
|
116
|
+
currentChainId = chain?.id ?? currentChainId;
|
|
117
|
+
}
|
|
118
|
+
// Return accounts with capabilities if wallet_connect was used, otherwise plain accounts
|
|
119
|
+
return {
|
|
120
|
+
accounts: (accountsWithCapabilities.length > 0
|
|
121
|
+
? accountsWithCapabilities
|
|
122
|
+
: accounts),
|
|
123
|
+
chainId: currentChainId,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
if (/(user closed modal|accounts received is empty|user denied account|request rejected)/i.test(error.message))
|
|
128
|
+
throw new UserRejectedRequestError(error);
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
async disconnect() {
|
|
133
|
+
const provider = await this.getProvider();
|
|
134
|
+
// Remove listeners
|
|
135
|
+
if (accountsChanged) {
|
|
136
|
+
provider.removeListener('accountsChanged', accountsChanged);
|
|
137
|
+
accountsChanged = undefined;
|
|
138
|
+
}
|
|
139
|
+
if (chainChanged) {
|
|
140
|
+
provider.removeListener('chainChanged', chainChanged);
|
|
141
|
+
chainChanged = undefined;
|
|
142
|
+
}
|
|
143
|
+
if (disconnect) {
|
|
144
|
+
provider.removeListener('disconnect', disconnect);
|
|
145
|
+
disconnect = undefined;
|
|
146
|
+
}
|
|
147
|
+
// Re-add connect listener for future connections
|
|
148
|
+
if (!connect) {
|
|
149
|
+
connect = this.onConnect.bind(this);
|
|
150
|
+
provider.on('connect', connect);
|
|
151
|
+
}
|
|
152
|
+
// Call provider disconnect
|
|
153
|
+
await provider.disconnect();
|
|
154
|
+
},
|
|
155
|
+
async getAccounts() {
|
|
156
|
+
const provider = await this.getProvider();
|
|
157
|
+
const accountsResult = await provider.request({
|
|
158
|
+
method: 'eth_accounts',
|
|
159
|
+
});
|
|
160
|
+
return parseAccounts(accountsResult);
|
|
161
|
+
},
|
|
162
|
+
async getChainId() {
|
|
163
|
+
const provider = await this.getProvider();
|
|
164
|
+
const chainId = await provider.request({ method: 'eth_chainId' });
|
|
165
|
+
return Number(chainId);
|
|
166
|
+
},
|
|
167
|
+
async getProvider() {
|
|
168
|
+
if (!provider_) {
|
|
169
|
+
sdk = JAW.create(parameters);
|
|
170
|
+
provider_ = sdk.provider;
|
|
171
|
+
}
|
|
172
|
+
return provider_;
|
|
173
|
+
},
|
|
174
|
+
async isAuthorized() {
|
|
175
|
+
try {
|
|
176
|
+
// Use retry strategy for reliability
|
|
177
|
+
const accounts = await withRetry(() => this.getAccounts());
|
|
178
|
+
return accounts.length > 0;
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
async switchChain({ chainId }) {
|
|
185
|
+
const chain = config.chains.find((x) => x.id === chainId);
|
|
186
|
+
if (!chain)
|
|
187
|
+
throw new SwitchChainError(new ChainNotConfiguredError());
|
|
188
|
+
const provider = await this.getProvider();
|
|
189
|
+
await provider.request({
|
|
190
|
+
method: 'wallet_switchEthereumChain',
|
|
191
|
+
params: [{ chainId: numberToHex(chainId) }],
|
|
192
|
+
});
|
|
193
|
+
return chain;
|
|
194
|
+
},
|
|
195
|
+
onAccountsChanged(accounts) {
|
|
196
|
+
if (accounts.length === 0)
|
|
197
|
+
this.onDisconnect();
|
|
198
|
+
else
|
|
199
|
+
config.emitter.emit('change', {
|
|
200
|
+
accounts: accounts.map((x) => getAddress(x)),
|
|
201
|
+
});
|
|
202
|
+
},
|
|
203
|
+
onChainChanged(chain) {
|
|
204
|
+
const chainId = Number(chain);
|
|
205
|
+
config.emitter.emit('change', { chainId });
|
|
206
|
+
},
|
|
207
|
+
async onConnect(connectInfo) {
|
|
208
|
+
const accounts = await this.getAccounts();
|
|
209
|
+
if (accounts.length === 0)
|
|
210
|
+
return;
|
|
211
|
+
const chainId = Number(connectInfo.chainId);
|
|
212
|
+
config.emitter.emit('connect', { accounts, chainId });
|
|
213
|
+
// Manage EIP-1193 event listeners
|
|
214
|
+
const provider = await this.getProvider();
|
|
215
|
+
if (connect) {
|
|
216
|
+
provider.removeListener('connect', connect);
|
|
217
|
+
connect = undefined;
|
|
218
|
+
}
|
|
219
|
+
if (!accountsChanged) {
|
|
220
|
+
accountsChanged = this.onAccountsChanged.bind(this);
|
|
221
|
+
provider.on('accountsChanged', accountsChanged);
|
|
222
|
+
}
|
|
223
|
+
if (!chainChanged) {
|
|
224
|
+
chainChanged = this.onChainChanged.bind(this);
|
|
225
|
+
provider.on('chainChanged', chainChanged);
|
|
226
|
+
}
|
|
227
|
+
if (!disconnect) {
|
|
228
|
+
disconnect = this.onDisconnect.bind(this);
|
|
229
|
+
provider.on('disconnect', disconnect);
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
async onDisconnect(_error) {
|
|
233
|
+
const provider = await this.getProvider();
|
|
234
|
+
config.emitter.emit('disconnect');
|
|
235
|
+
// Manage EIP-1193 event listeners
|
|
236
|
+
if (accountsChanged) {
|
|
237
|
+
provider.removeListener('accountsChanged', accountsChanged);
|
|
238
|
+
accountsChanged = undefined;
|
|
239
|
+
}
|
|
240
|
+
if (chainChanged) {
|
|
241
|
+
provider.removeListener('chainChanged', chainChanged);
|
|
242
|
+
chainChanged = undefined;
|
|
243
|
+
}
|
|
244
|
+
if (disconnect) {
|
|
245
|
+
provider.removeListener('disconnect', disconnect);
|
|
246
|
+
disconnect = undefined;
|
|
247
|
+
}
|
|
248
|
+
if (!connect) {
|
|
249
|
+
connect = this.onConnect.bind(this);
|
|
250
|
+
provider.on('connect', connect);
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
}));
|
|
254
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Connector.test.d.ts","sourceRoot":"","sources":["../../src/lib/Connector.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { expect, test } from 'vitest';
|
|
2
|
+
import { jaw } from './Connector.js';
|
|
3
|
+
test('setup', () => {
|
|
4
|
+
const connectorFn = jaw({
|
|
5
|
+
apiKey: 'test-api-key',
|
|
6
|
+
});
|
|
7
|
+
expect(jaw.type).toEqual('jaw');
|
|
8
|
+
expect(typeof connectorFn).toBe('function');
|
|
9
|
+
});
|
|
10
|
+
test('setup with parameters', () => {
|
|
11
|
+
const connectorFn = jaw({
|
|
12
|
+
apiKey: 'test-api-key',
|
|
13
|
+
appName: 'Test App',
|
|
14
|
+
appLogoUrl: 'https://example.com/logo.png',
|
|
15
|
+
});
|
|
16
|
+
expect(jaw.type).toEqual('jaw');
|
|
17
|
+
expect(typeof connectorFn).toBe('function');
|
|
18
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Hooks.d.ts","sourceRoot":"","sources":["../../src/lib/Hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,OAAO,EACP,kBAAkB,GACnB,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useConnect, useDisconnect, useGrantPermissions, useRevokePermissions, usePermissions, useGetAssets, useCapabilities, useSign, useGetCallsHistory, } from './internal/react.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Query.d.ts","sourceRoot":"","sources":["../../src/lib/Query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getPermissionsQueryKey, getAssetsQueryKey, getCapabilitiesQueryKey, getCallsHistoryQueryKey } from './internal/query.js';
|