@fastnear/wallet-adapter 0.1.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 +174 -0
- package/dist/index.cjs +167 -0
- package/dist/index.d.ts +199 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +147 -0
- package/package.json +20 -0
package/README.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# @fastnear/wallet-adapter
|
|
2
|
+
|
|
3
|
+
A lightweight, dependency-free client interface for integrating NEAR wallets into your dApp.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 Zero dependencies
|
|
8
|
+
- 📱 Works with all major NEAR wallets
|
|
9
|
+
- 💪 Full TypeScript support
|
|
10
|
+
- 🔒 Secure iframe-based design
|
|
11
|
+
- 📦 ESM and CommonJS support
|
|
12
|
+
- 🎯 Simple, promise-based API
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @fastnear/wallet-adapter
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Basic Usage
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
import { WalletAdapter } from '@fastnear/wallet-adapter';
|
|
24
|
+
|
|
25
|
+
// Create adapter instance
|
|
26
|
+
const adapter = new WalletAdapter();
|
|
27
|
+
|
|
28
|
+
// Sign in
|
|
29
|
+
const result = await adapter.signIn({
|
|
30
|
+
networkId: 'mainnet',
|
|
31
|
+
contractId: 'example.near',
|
|
32
|
+
wallet: 'near' // optional, defaults to user choice
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (result.url) {
|
|
36
|
+
// Redirect to wallet
|
|
37
|
+
window.location.href = result.url;
|
|
38
|
+
} else if (result.accountId) {
|
|
39
|
+
console.log('Signed in as:', result.accountId);
|
|
40
|
+
} else if (result.error) {
|
|
41
|
+
console.error('Failed to sign in:', result.error);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Send transaction
|
|
45
|
+
const txResult = await adapter.sendTransaction({
|
|
46
|
+
receiverId: 'example.near',
|
|
47
|
+
actions: [{
|
|
48
|
+
type: 'FunctionCall',
|
|
49
|
+
params: {
|
|
50
|
+
methodName: 'example_method',
|
|
51
|
+
args: { /* ... */ },
|
|
52
|
+
gas: '30000000000000',
|
|
53
|
+
deposit: '0'
|
|
54
|
+
}
|
|
55
|
+
}]
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (txResult.url) {
|
|
59
|
+
window.location.href = txResult.url;
|
|
60
|
+
} else if (txResult.hash) {
|
|
61
|
+
console.log('Transaction hash:', txResult.hash);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Clean up when done
|
|
65
|
+
adapter.destroy();
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Advanced Configuration
|
|
69
|
+
|
|
70
|
+
```javascript
|
|
71
|
+
const adapter = new WalletAdapter({
|
|
72
|
+
// Custom widget URL (defaults to official hosted version)
|
|
73
|
+
widgetUrl: 'https://your-domain.com/wallet-widget/',
|
|
74
|
+
|
|
75
|
+
// Restrict message origin for security (defaults to '*')
|
|
76
|
+
targetOrigin: 'https://your-domain.com',
|
|
77
|
+
|
|
78
|
+
// Handle wallet state updates
|
|
79
|
+
onStateUpdate: (state) => {
|
|
80
|
+
localStorage.setItem('wallet-state', JSON.stringify(state));
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## API Reference
|
|
86
|
+
|
|
87
|
+
### `new WalletAdapter(config?)`
|
|
88
|
+
|
|
89
|
+
Creates a new wallet adapter instance.
|
|
90
|
+
|
|
91
|
+
#### Config Options
|
|
92
|
+
- `widgetUrl?: string` - URL of the wallet widget (defaults to official hosted version)
|
|
93
|
+
- `targetOrigin?: string` - Target origin for postMessage (defaults to '*')
|
|
94
|
+
- `onStateUpdate?: (state: WalletState) => void` - Called when wallet state changes
|
|
95
|
+
|
|
96
|
+
### `signIn(config)`
|
|
97
|
+
|
|
98
|
+
Signs in with a NEAR wallet.
|
|
99
|
+
|
|
100
|
+
#### Config
|
|
101
|
+
```typescript
|
|
102
|
+
{
|
|
103
|
+
networkId: 'mainnet' | 'testnet',
|
|
104
|
+
contractId: string,
|
|
105
|
+
wallet?: 'near' | 'here' | 'meteor'
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### Returns
|
|
110
|
+
```typescript
|
|
111
|
+
Promise<{
|
|
112
|
+
url?: string, // URL to redirect to if needed
|
|
113
|
+
accountId?: string, // Account ID if immediately available
|
|
114
|
+
error?: string // Error message if sign in failed
|
|
115
|
+
}>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### `sendTransaction(config)`
|
|
119
|
+
|
|
120
|
+
Sends a transaction using the connected wallet.
|
|
121
|
+
|
|
122
|
+
#### Config
|
|
123
|
+
```typescript
|
|
124
|
+
{
|
|
125
|
+
receiverId: string,
|
|
126
|
+
actions: Array<{
|
|
127
|
+
type: string,
|
|
128
|
+
params: {
|
|
129
|
+
methodName?: string,
|
|
130
|
+
args?: Object,
|
|
131
|
+
gas?: string,
|
|
132
|
+
deposit?: string
|
|
133
|
+
}
|
|
134
|
+
}>,
|
|
135
|
+
wallet?: 'near' | 'here' | 'meteor'
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### Returns
|
|
140
|
+
```typescript
|
|
141
|
+
Promise<{
|
|
142
|
+
url?: string, // URL to redirect to if needed
|
|
143
|
+
hash?: string, // Transaction hash if immediately available
|
|
144
|
+
error?: string // Error message if transaction failed
|
|
145
|
+
}>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### `getState()`
|
|
149
|
+
|
|
150
|
+
Gets current wallet state.
|
|
151
|
+
|
|
152
|
+
#### Returns
|
|
153
|
+
```typescript
|
|
154
|
+
{
|
|
155
|
+
accountId?: string, // NEAR account ID if signed in
|
|
156
|
+
publicKey?: string, // Public key if available
|
|
157
|
+
privateKey?: string, // Private key if available
|
|
158
|
+
lastWalletId?: string // ID of last used wallet
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### `destroy()`
|
|
163
|
+
|
|
164
|
+
Cleans up adapter resources. Should be called when adapter is no longer needed.
|
|
165
|
+
|
|
166
|
+
## Supported Wallets
|
|
167
|
+
|
|
168
|
+
- NEAR Wallet (MyNearWallet)
|
|
169
|
+
- HERE Wallet
|
|
170
|
+
- Meteor Wallet
|
|
171
|
+
|
|
172
|
+
## License
|
|
173
|
+
|
|
174
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/index.js
|
|
20
|
+
var src_exports = {};
|
|
21
|
+
__export(src_exports, {
|
|
22
|
+
WalletAdapter: () => WalletAdapter
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(src_exports);
|
|
25
|
+
var WalletAdapter = class _WalletAdapter {
|
|
26
|
+
/** @type {HTMLIFrameElement} */
|
|
27
|
+
#iframe = null;
|
|
28
|
+
/** @type {string} */
|
|
29
|
+
#targetOrigin;
|
|
30
|
+
/** @type {string} */
|
|
31
|
+
#widgetUrl;
|
|
32
|
+
/** @type {Map<string, Function>} */
|
|
33
|
+
#pending = /* @__PURE__ */ new Map();
|
|
34
|
+
/** @type {WalletState} */
|
|
35
|
+
#state = {};
|
|
36
|
+
/** @type {Function} */
|
|
37
|
+
#onStateUpdate;
|
|
38
|
+
/** @type {string} */
|
|
39
|
+
#callbackUrl;
|
|
40
|
+
/** @type {string} */
|
|
41
|
+
static defaultWidgetUrl = "https://wallet-adapter.fastnear.com";
|
|
42
|
+
/**
|
|
43
|
+
* @param {WalletAdapterConfig} [config]
|
|
44
|
+
*/
|
|
45
|
+
constructor({
|
|
46
|
+
widgetUrl = _WalletAdapter.defaultWidgetUrl,
|
|
47
|
+
targetOrigin = "*",
|
|
48
|
+
onStateUpdate,
|
|
49
|
+
callbackUrl = window.location.href
|
|
50
|
+
} = {}) {
|
|
51
|
+
this.#targetOrigin = targetOrigin;
|
|
52
|
+
this.#widgetUrl = widgetUrl;
|
|
53
|
+
this.#onStateUpdate = onStateUpdate;
|
|
54
|
+
this.#callbackUrl = callbackUrl;
|
|
55
|
+
window.addEventListener("message", this.#handleMessage.bind(this));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Creates an iframe for wallet interaction
|
|
59
|
+
* @param {string} path - Path to load in iframe
|
|
60
|
+
* @returns {HTMLIFrameElement}
|
|
61
|
+
*/
|
|
62
|
+
#createIframe(path) {
|
|
63
|
+
if (this.#iframe) {
|
|
64
|
+
this.#iframe.remove();
|
|
65
|
+
}
|
|
66
|
+
const url = new URL(path, this.#widgetUrl);
|
|
67
|
+
const iframe = document.createElement("iframe");
|
|
68
|
+
iframe.src = url.toString();
|
|
69
|
+
iframe.allow = "usb";
|
|
70
|
+
iframe.style.border = "none";
|
|
71
|
+
iframe.style.zIndex = "10000";
|
|
72
|
+
iframe.style.position = "fixed";
|
|
73
|
+
iframe.style.display = "block";
|
|
74
|
+
iframe.style.top = "0";
|
|
75
|
+
iframe.style.left = "0";
|
|
76
|
+
iframe.style.width = "100%";
|
|
77
|
+
iframe.style.height = "100%";
|
|
78
|
+
document.body.appendChild(iframe);
|
|
79
|
+
this.#iframe = iframe;
|
|
80
|
+
return iframe;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Handles messages from the wallet widget
|
|
84
|
+
* @param {MessageEvent} event
|
|
85
|
+
*/
|
|
86
|
+
#handleMessage(event) {
|
|
87
|
+
if (this.#targetOrigin !== "*" && event.origin !== this.#targetOrigin) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const { id, type, action, payload } = event.data;
|
|
91
|
+
if (type !== "wallet-adapter")
|
|
92
|
+
return;
|
|
93
|
+
if (action === "close") {
|
|
94
|
+
this.#iframe?.remove();
|
|
95
|
+
this.#iframe = null;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (payload?.state) {
|
|
99
|
+
this.#state = { ...this.#state, ...payload.state };
|
|
100
|
+
this.#onStateUpdate?.(this.#state);
|
|
101
|
+
}
|
|
102
|
+
const resolve = this.#pending.get(id);
|
|
103
|
+
if (resolve) {
|
|
104
|
+
this.#pending.delete(id);
|
|
105
|
+
this.#iframe?.remove();
|
|
106
|
+
this.#iframe = null;
|
|
107
|
+
resolve(payload);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Sends a message to the wallet widget
|
|
112
|
+
* @param {string} path - Path to load in iframe
|
|
113
|
+
* @param {string} method - Method to call
|
|
114
|
+
* @param {Object} params - Parameters to pass
|
|
115
|
+
* @returns {Promise<any>}
|
|
116
|
+
*/
|
|
117
|
+
async #sendMessage(path, method, params) {
|
|
118
|
+
return new Promise((resolve) => {
|
|
119
|
+
const id = Math.random().toString(36).slice(2);
|
|
120
|
+
this.#pending.set(id, resolve);
|
|
121
|
+
const iframe = this.#createIframe(path);
|
|
122
|
+
iframe.onload = () => {
|
|
123
|
+
iframe.contentWindow?.postMessage({
|
|
124
|
+
type: "wallet-adapter",
|
|
125
|
+
method,
|
|
126
|
+
params: {
|
|
127
|
+
id,
|
|
128
|
+
...params,
|
|
129
|
+
state: this.#state,
|
|
130
|
+
callbackUrl: params.callbackUrl || this.#callbackUrl
|
|
131
|
+
}
|
|
132
|
+
}, this.#targetOrigin);
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get current wallet state
|
|
138
|
+
* @returns {WalletState}
|
|
139
|
+
*/
|
|
140
|
+
getState() {
|
|
141
|
+
return { ...this.#state };
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Sign in with a NEAR wallet
|
|
145
|
+
* @param {SignInConfig} config
|
|
146
|
+
* @returns {Promise<SignInResult>}
|
|
147
|
+
*/
|
|
148
|
+
async signIn(config) {
|
|
149
|
+
return this.#sendMessage("/login.html", "signIn", config);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Send a transaction using connected wallet
|
|
153
|
+
* @param {TransactionConfig} config
|
|
154
|
+
* @returns {Promise<TransactionResult>}
|
|
155
|
+
*/
|
|
156
|
+
async sendTransaction(config) {
|
|
157
|
+
return this.#sendMessage("/sign.html", "sendTransaction", config);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Clean up adapter resources
|
|
161
|
+
*/
|
|
162
|
+
destroy() {
|
|
163
|
+
window.removeEventListener("message", this.#handleMessage);
|
|
164
|
+
this.#iframe?.remove();
|
|
165
|
+
this.#iframe = null;
|
|
166
|
+
}
|
|
167
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} WalletState
|
|
3
|
+
* @property {string} [accountId] - NEAR account ID if signed in
|
|
4
|
+
* @property {string} [publicKey] - Public key if available
|
|
5
|
+
* @property {string} [privateKey] - Private key if available
|
|
6
|
+
* @property {string} [lastWalletId] - ID of last used wallet
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {Object} WalletAction
|
|
10
|
+
* @property {string} type - Action type
|
|
11
|
+
* @property {Object} [args] - Action arguments
|
|
12
|
+
* @property {string|number} [gas] - Gas to attach
|
|
13
|
+
* @property {string|number} [deposit] - Deposit to attach
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {Object} SignInConfig
|
|
17
|
+
* @property {string} networkId - NEAR network ID ('mainnet' or 'testnet')
|
|
18
|
+
* @property {string} contractId - Contract ID to request access for
|
|
19
|
+
* @property {'near'|'here'|'meteor'} [wallet] - Preferred wallet to use
|
|
20
|
+
* @property {string} [callbackUrl] - URL to redirect back to after wallet interaction
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* @typedef {Object} SignInResult
|
|
24
|
+
* @property {string} [url] - URL to redirect to if needed
|
|
25
|
+
* @property {string} [accountId] - Account ID if immediately available
|
|
26
|
+
* @property {string} [error] - Error message if sign in failed
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* @typedef {Object} TransactionConfig
|
|
30
|
+
* @property {string} receiverId - Transaction receiver account ID
|
|
31
|
+
* @property {WalletAction[]} actions - Transaction actions to perform
|
|
32
|
+
* @property {'near'|'here'|'meteor'} [wallet] - Preferred wallet to use
|
|
33
|
+
* @property {string} [callbackUrl] - URL to redirect back to after wallet interaction
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* @typedef {Object} TransactionResult
|
|
37
|
+
* @property {string} [url] - URL to redirect to if needed
|
|
38
|
+
* @property {string} [hash] - Transaction hash if immediately available
|
|
39
|
+
* @property {string} [error] - Error message if transaction failed
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* @typedef {Object} WalletAdapterConfig
|
|
43
|
+
* @property {string} [widgetUrl] - URL of the wallet widget (defaults to official hosted version)
|
|
44
|
+
* @property {string} [targetOrigin] - Target origin for postMessage (defaults to '*')
|
|
45
|
+
* @property {(state: WalletState) => void} [onStateUpdate] - Called when wallet state changes
|
|
46
|
+
* @property {string} [callbackUrl] - Default callback URL for wallet interactions (defaults to current page URL)
|
|
47
|
+
*/
|
|
48
|
+
/**
|
|
49
|
+
* Interface for interacting with NEAR wallets
|
|
50
|
+
*/
|
|
51
|
+
export class WalletAdapter {
|
|
52
|
+
/** @type {string} */
|
|
53
|
+
static defaultWidgetUrl: string;
|
|
54
|
+
/**
|
|
55
|
+
* @param {WalletAdapterConfig} [config]
|
|
56
|
+
*/
|
|
57
|
+
constructor({ widgetUrl, targetOrigin, onStateUpdate, callbackUrl }?: WalletAdapterConfig);
|
|
58
|
+
/**
|
|
59
|
+
* Get current wallet state
|
|
60
|
+
* @returns {WalletState}
|
|
61
|
+
*/
|
|
62
|
+
getState(): WalletState;
|
|
63
|
+
/**
|
|
64
|
+
* Sign in with a NEAR wallet
|
|
65
|
+
* @param {SignInConfig} config
|
|
66
|
+
* @returns {Promise<SignInResult>}
|
|
67
|
+
*/
|
|
68
|
+
signIn(config: SignInConfig): Promise<SignInResult>;
|
|
69
|
+
/**
|
|
70
|
+
* Send a transaction using connected wallet
|
|
71
|
+
* @param {TransactionConfig} config
|
|
72
|
+
* @returns {Promise<TransactionResult>}
|
|
73
|
+
*/
|
|
74
|
+
sendTransaction(config: TransactionConfig): Promise<TransactionResult>;
|
|
75
|
+
/**
|
|
76
|
+
* Clean up adapter resources
|
|
77
|
+
*/
|
|
78
|
+
destroy(): void;
|
|
79
|
+
#private;
|
|
80
|
+
}
|
|
81
|
+
export type WalletState = {
|
|
82
|
+
/**
|
|
83
|
+
* - NEAR account ID if signed in
|
|
84
|
+
*/
|
|
85
|
+
accountId?: string;
|
|
86
|
+
/**
|
|
87
|
+
* - Public key if available
|
|
88
|
+
*/
|
|
89
|
+
publicKey?: string;
|
|
90
|
+
/**
|
|
91
|
+
* - Private key if available
|
|
92
|
+
*/
|
|
93
|
+
privateKey?: string;
|
|
94
|
+
/**
|
|
95
|
+
* - ID of last used wallet
|
|
96
|
+
*/
|
|
97
|
+
lastWalletId?: string;
|
|
98
|
+
};
|
|
99
|
+
export type WalletAction = {
|
|
100
|
+
/**
|
|
101
|
+
* - Action type
|
|
102
|
+
*/
|
|
103
|
+
type: string;
|
|
104
|
+
/**
|
|
105
|
+
* - Action arguments
|
|
106
|
+
*/
|
|
107
|
+
args?: any;
|
|
108
|
+
/**
|
|
109
|
+
* - Gas to attach
|
|
110
|
+
*/
|
|
111
|
+
gas?: string | number;
|
|
112
|
+
/**
|
|
113
|
+
* - Deposit to attach
|
|
114
|
+
*/
|
|
115
|
+
deposit?: string | number;
|
|
116
|
+
};
|
|
117
|
+
export type SignInConfig = {
|
|
118
|
+
/**
|
|
119
|
+
* - NEAR network ID ('mainnet' or 'testnet')
|
|
120
|
+
*/
|
|
121
|
+
networkId: string;
|
|
122
|
+
/**
|
|
123
|
+
* - Contract ID to request access for
|
|
124
|
+
*/
|
|
125
|
+
contractId: string;
|
|
126
|
+
/**
|
|
127
|
+
* - Preferred wallet to use
|
|
128
|
+
*/
|
|
129
|
+
wallet?: "near" | "here" | "meteor";
|
|
130
|
+
/**
|
|
131
|
+
* - URL to redirect back to after wallet interaction
|
|
132
|
+
*/
|
|
133
|
+
callbackUrl?: string;
|
|
134
|
+
};
|
|
135
|
+
export type SignInResult = {
|
|
136
|
+
/**
|
|
137
|
+
* - URL to redirect to if needed
|
|
138
|
+
*/
|
|
139
|
+
url?: string;
|
|
140
|
+
/**
|
|
141
|
+
* - Account ID if immediately available
|
|
142
|
+
*/
|
|
143
|
+
accountId?: string;
|
|
144
|
+
/**
|
|
145
|
+
* - Error message if sign in failed
|
|
146
|
+
*/
|
|
147
|
+
error?: string;
|
|
148
|
+
};
|
|
149
|
+
export type TransactionConfig = {
|
|
150
|
+
/**
|
|
151
|
+
* - Transaction receiver account ID
|
|
152
|
+
*/
|
|
153
|
+
receiverId: string;
|
|
154
|
+
/**
|
|
155
|
+
* - Transaction actions to perform
|
|
156
|
+
*/
|
|
157
|
+
actions: WalletAction[];
|
|
158
|
+
/**
|
|
159
|
+
* - Preferred wallet to use
|
|
160
|
+
*/
|
|
161
|
+
wallet?: "near" | "here" | "meteor";
|
|
162
|
+
/**
|
|
163
|
+
* - URL to redirect back to after wallet interaction
|
|
164
|
+
*/
|
|
165
|
+
callbackUrl?: string;
|
|
166
|
+
};
|
|
167
|
+
export type TransactionResult = {
|
|
168
|
+
/**
|
|
169
|
+
* - URL to redirect to if needed
|
|
170
|
+
*/
|
|
171
|
+
url?: string;
|
|
172
|
+
/**
|
|
173
|
+
* - Transaction hash if immediately available
|
|
174
|
+
*/
|
|
175
|
+
hash?: string;
|
|
176
|
+
/**
|
|
177
|
+
* - Error message if transaction failed
|
|
178
|
+
*/
|
|
179
|
+
error?: string;
|
|
180
|
+
};
|
|
181
|
+
export type WalletAdapterConfig = {
|
|
182
|
+
/**
|
|
183
|
+
* - URL of the wallet widget (defaults to official hosted version)
|
|
184
|
+
*/
|
|
185
|
+
widgetUrl?: string;
|
|
186
|
+
/**
|
|
187
|
+
* - Target origin for postMessage (defaults to '*')
|
|
188
|
+
*/
|
|
189
|
+
targetOrigin?: string;
|
|
190
|
+
/**
|
|
191
|
+
* - Called when wallet state changes
|
|
192
|
+
*/
|
|
193
|
+
onStateUpdate?: (state: WalletState) => void;
|
|
194
|
+
/**
|
|
195
|
+
* - Default callback URL for wallet interactions (defaults to current page URL)
|
|
196
|
+
*/
|
|
197
|
+
callbackUrl?: string;
|
|
198
|
+
};
|
|
199
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;GAMG;AAEH;;;;;;GAMG;AAEH;;;;;GAKG;AAEH;;;;;;GAMG;AAEH;;;;;GAKG;AAEH;;;;;;GAMG;AAEH;;GAEG;AACH;IAsBI,qBAAqB;IACrB,yBADW,MAAM,CAC+C;IAEhE;;OAEG;IACH,sEAFW,mBAAmB,EAa7B;IAmGD;;;OAGG;IACH,YAFa,WAAW,CAIvB;IAED;;;;OAIG;IACH,eAHW,YAAY,GACV,OAAO,CAAC,YAAY,CAAC,CAIjC;IAED;;;;OAIG;IACH,wBAHW,iBAAiB,GACf,OAAO,CAAC,iBAAiB,CAAC,CAItC;IAED;;OAEG;IACH,gBAIC;;CACF;;;;;gBAnOW,MAAM;;;;gBACN,MAAM;;;;iBACN,MAAM;;;;mBACN,MAAM;;;;;;UAKN,MAAM;;;;;;;;UAEN,MAAM,GAAC,MAAM;;;;cACb,MAAM,GAAC,MAAM;;;;;;eAKb,MAAM;;;;gBACN,MAAM;;;;aACN,MAAM,GAAC,MAAM,GAAC,QAAQ;;;;kBACtB,MAAM;;;;;;UAKN,MAAM;;;;gBACN,MAAM;;;;YACN,MAAM;;;;;;gBAKN,MAAM;;;;aACN,YAAY,EAAE;;;;aACd,MAAM,GAAC,MAAM,GAAC,QAAQ;;;;kBACtB,MAAM;;;;;;UAKN,MAAM;;;;WACN,MAAM;;;;YACN,MAAM;;;;;;gBAKN,MAAM;;;;mBACN,MAAM;;;;oBACN,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI;;;;kBAC5B,MAAM"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// src/index.js
|
|
2
|
+
var WalletAdapter = class _WalletAdapter {
|
|
3
|
+
/** @type {HTMLIFrameElement} */
|
|
4
|
+
#iframe = null;
|
|
5
|
+
/** @type {string} */
|
|
6
|
+
#targetOrigin;
|
|
7
|
+
/** @type {string} */
|
|
8
|
+
#widgetUrl;
|
|
9
|
+
/** @type {Map<string, Function>} */
|
|
10
|
+
#pending = /* @__PURE__ */ new Map();
|
|
11
|
+
/** @type {WalletState} */
|
|
12
|
+
#state = {};
|
|
13
|
+
/** @type {Function} */
|
|
14
|
+
#onStateUpdate;
|
|
15
|
+
/** @type {string} */
|
|
16
|
+
#callbackUrl;
|
|
17
|
+
/** @type {string} */
|
|
18
|
+
static defaultWidgetUrl = "https://wallet-adapter.fastnear.com";
|
|
19
|
+
/**
|
|
20
|
+
* @param {WalletAdapterConfig} [config]
|
|
21
|
+
*/
|
|
22
|
+
constructor({
|
|
23
|
+
widgetUrl = _WalletAdapter.defaultWidgetUrl,
|
|
24
|
+
targetOrigin = "*",
|
|
25
|
+
onStateUpdate,
|
|
26
|
+
callbackUrl = window.location.href
|
|
27
|
+
} = {}) {
|
|
28
|
+
this.#targetOrigin = targetOrigin;
|
|
29
|
+
this.#widgetUrl = widgetUrl;
|
|
30
|
+
this.#onStateUpdate = onStateUpdate;
|
|
31
|
+
this.#callbackUrl = callbackUrl;
|
|
32
|
+
window.addEventListener("message", this.#handleMessage.bind(this));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Creates an iframe for wallet interaction
|
|
36
|
+
* @param {string} path - Path to load in iframe
|
|
37
|
+
* @returns {HTMLIFrameElement}
|
|
38
|
+
*/
|
|
39
|
+
#createIframe(path) {
|
|
40
|
+
if (this.#iframe) {
|
|
41
|
+
this.#iframe.remove();
|
|
42
|
+
}
|
|
43
|
+
const url = new URL(path, this.#widgetUrl);
|
|
44
|
+
const iframe = document.createElement("iframe");
|
|
45
|
+
iframe.src = url.toString();
|
|
46
|
+
iframe.allow = "usb";
|
|
47
|
+
iframe.style.border = "none";
|
|
48
|
+
iframe.style.zIndex = "10000";
|
|
49
|
+
iframe.style.position = "fixed";
|
|
50
|
+
iframe.style.display = "block";
|
|
51
|
+
iframe.style.top = "0";
|
|
52
|
+
iframe.style.left = "0";
|
|
53
|
+
iframe.style.width = "100%";
|
|
54
|
+
iframe.style.height = "100%";
|
|
55
|
+
document.body.appendChild(iframe);
|
|
56
|
+
this.#iframe = iframe;
|
|
57
|
+
return iframe;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Handles messages from the wallet widget
|
|
61
|
+
* @param {MessageEvent} event
|
|
62
|
+
*/
|
|
63
|
+
#handleMessage(event) {
|
|
64
|
+
if (this.#targetOrigin !== "*" && event.origin !== this.#targetOrigin) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const { id, type, action, payload } = event.data;
|
|
68
|
+
if (type !== "wallet-adapter")
|
|
69
|
+
return;
|
|
70
|
+
if (action === "close") {
|
|
71
|
+
this.#iframe?.remove();
|
|
72
|
+
this.#iframe = null;
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (payload?.state) {
|
|
76
|
+
this.#state = { ...this.#state, ...payload.state };
|
|
77
|
+
this.#onStateUpdate?.(this.#state);
|
|
78
|
+
}
|
|
79
|
+
const resolve = this.#pending.get(id);
|
|
80
|
+
if (resolve) {
|
|
81
|
+
this.#pending.delete(id);
|
|
82
|
+
this.#iframe?.remove();
|
|
83
|
+
this.#iframe = null;
|
|
84
|
+
resolve(payload);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Sends a message to the wallet widget
|
|
89
|
+
* @param {string} path - Path to load in iframe
|
|
90
|
+
* @param {string} method - Method to call
|
|
91
|
+
* @param {Object} params - Parameters to pass
|
|
92
|
+
* @returns {Promise<any>}
|
|
93
|
+
*/
|
|
94
|
+
async #sendMessage(path, method, params) {
|
|
95
|
+
return new Promise((resolve) => {
|
|
96
|
+
const id = Math.random().toString(36).slice(2);
|
|
97
|
+
this.#pending.set(id, resolve);
|
|
98
|
+
const iframe = this.#createIframe(path);
|
|
99
|
+
iframe.onload = () => {
|
|
100
|
+
iframe.contentWindow?.postMessage({
|
|
101
|
+
type: "wallet-adapter",
|
|
102
|
+
method,
|
|
103
|
+
params: {
|
|
104
|
+
id,
|
|
105
|
+
...params,
|
|
106
|
+
state: this.#state,
|
|
107
|
+
callbackUrl: params.callbackUrl || this.#callbackUrl
|
|
108
|
+
}
|
|
109
|
+
}, this.#targetOrigin);
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get current wallet state
|
|
115
|
+
* @returns {WalletState}
|
|
116
|
+
*/
|
|
117
|
+
getState() {
|
|
118
|
+
return { ...this.#state };
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Sign in with a NEAR wallet
|
|
122
|
+
* @param {SignInConfig} config
|
|
123
|
+
* @returns {Promise<SignInResult>}
|
|
124
|
+
*/
|
|
125
|
+
async signIn(config) {
|
|
126
|
+
return this.#sendMessage("/login.html", "signIn", config);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Send a transaction using connected wallet
|
|
130
|
+
* @param {TransactionConfig} config
|
|
131
|
+
* @returns {Promise<TransactionResult>}
|
|
132
|
+
*/
|
|
133
|
+
async sendTransaction(config) {
|
|
134
|
+
return this.#sendMessage("/sign.html", "sendTransaction", config);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Clean up adapter resources
|
|
138
|
+
*/
|
|
139
|
+
destroy() {
|
|
140
|
+
window.removeEventListener("message", this.#handleMessage);
|
|
141
|
+
this.#iframe?.remove();
|
|
142
|
+
this.#iframe = null;
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
export {
|
|
146
|
+
WalletAdapter
|
|
147
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fastnear/wallet-adapter",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Client interface for NEAR wallet adapter",
|
|
5
|
+
"repository": "https://github.com/fastnear/wallet-adapter.git",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"files": ["dist"],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "node build.js && npm run types",
|
|
13
|
+
"types": "tsc",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"esbuild": "^0.19.0",
|
|
18
|
+
"typescript": "^5.0.0"
|
|
19
|
+
}
|
|
20
|
+
}
|