@orbi-wallet/sdk 0.0.4 → 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 +38 -238
- package/dist/client.d.ts +28 -96
- package/dist/client.js +111 -217
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -3
- package/dist/types.d.ts +8 -26
- package/dist/version.d.ts +2 -0
- package/dist/version.js +6 -0
- package/package.json +15 -12
- package/dist/wallet.d.ts +0 -16
- package/dist/wallet.js +0 -33
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @orbi-wallet/sdk
|
|
2
2
|
|
|
3
|
-
The official SDK for
|
|
3
|
+
The official SDK for connecting your Stellar dApp to [Orbi Smart Wallet](https://orbiwallet.xyz).
|
|
4
4
|
|
|
5
|
-
Orbi is a passkey-
|
|
5
|
+
Orbi is a passkey-secured **classic Stellar (G) account** wallet. Users sign in and approve transactions with Face ID / Touch ID — no seed phrase, no browser extension.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -14,290 +14,90 @@ npm install @orbi-wallet/sdk
|
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
-
## Quick
|
|
18
|
-
|
|
19
|
-
### User pays gas (default)
|
|
20
|
-
|
|
21
|
-
```ts
|
|
22
|
-
import { OrbiClient } from '@orbi-wallet/sdk';
|
|
23
|
-
|
|
24
|
-
const orbi = new OrbiClient({
|
|
25
|
-
apiUrl: 'https://api.orbiwallet.xyz',
|
|
26
|
-
});
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### dApp sponsors gas (gasless)
|
|
17
|
+
## Quick start
|
|
30
18
|
|
|
31
19
|
```ts
|
|
32
20
|
import { OrbiClient } from '@orbi-wallet/sdk';
|
|
33
21
|
|
|
34
|
-
const orbi = new OrbiClient({
|
|
35
|
-
apiUrl: 'https://api.orbiwallet.xyz',
|
|
36
|
-
apiKey: 'YOUR_API_KEY', // get this from developers.orbiwallet.xyz
|
|
37
|
-
});
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
That one line is the only difference. Everything else — connecting, signing, submitting — works exactly the same. Users see the fee crossed out and "Sponsored by [your app]".
|
|
22
|
+
const orbi = new OrbiClient({ network: 'testnet' });
|
|
41
23
|
|
|
42
|
-
|
|
24
|
+
// 1. Connect — opens a popup, resolves once the user approves
|
|
25
|
+
const { walletAddress } = await orbi.connect();
|
|
43
26
|
|
|
44
|
-
|
|
27
|
+
// 2. Build a transaction with @stellar/stellar-sdk and get its XDR
|
|
28
|
+
const xdr = transaction.toXDR();
|
|
45
29
|
|
|
46
|
-
|
|
30
|
+
// 3. Ask the user to review and sign — opens a popup, resolves with the signed XDR
|
|
31
|
+
const { signedXdr } = await orbi.signTransaction({ xdr });
|
|
47
32
|
|
|
48
|
-
|
|
49
|
-
1. orbi.connect() → redirect user to Orbi to connect wallet
|
|
50
|
-
2. orbi.handleCallback() → on return, get wallet address + passkey ID
|
|
51
|
-
3. orbi.sign() → redirect user to approve transaction with passkey
|
|
52
|
-
4. orbi.handleSignCallback() + orbi.bundle() → submit signed tx to relay
|
|
53
|
-
5. orbi.waitForConfirmation(opId) → wait for on-chain confirmation (~5s)
|
|
33
|
+
// 4. Submit signedXdr to Horizon yourself (e.g. server.submitTransaction)
|
|
54
34
|
```
|
|
55
35
|
|
|
56
36
|
---
|
|
57
37
|
|
|
58
|
-
##
|
|
59
|
-
|
|
60
|
-
### Step 1 — Connect wallet
|
|
38
|
+
## How it works
|
|
61
39
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
```ts
|
|
65
|
-
orbi.connect({
|
|
66
|
-
redirectUrl: 'https://yourapp.com/callback',
|
|
67
|
-
});
|
|
68
|
-
// navigates to keys.orbiwallet.xyz, then back to redirectUrl?token=...
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
On your `/callback` page:
|
|
72
|
-
|
|
73
|
-
```ts
|
|
74
|
-
const wallet = await orbi.handleCallback();
|
|
75
|
-
if (wallet) {
|
|
76
|
-
// { walletAddress, passkeyId, email }
|
|
77
|
-
localStorage.setItem('walletAddress', wallet.walletAddress);
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Step 2 — Sign and submit a transaction
|
|
82
|
-
|
|
83
|
-
```ts
|
|
84
|
-
// Redirect user to approve
|
|
85
|
-
orbi.sign({
|
|
86
|
-
walletAddress: localStorage.getItem('walletAddress')!,
|
|
87
|
-
contractId: 'YOUR_CONTRACT_ID',
|
|
88
|
-
functionName: 'transfer',
|
|
89
|
-
argsXdr: ['...', '...'], // XDR-encoded args
|
|
90
|
-
redirectUrl: 'https://yourapp.com/sign-callback',
|
|
91
|
-
});
|
|
92
|
-
```
|
|
40
|
+
Orbi uses a **popup + postMessage** handshake — the same integration pattern Coinbase Smart Wallet and most modern wallet SDKs use:
|
|
93
41
|
|
|
94
|
-
|
|
42
|
+
1. `orbi.connect()` / `orbi.signTransaction()` opens `keys.orbiwallet.xyz` in a popup
|
|
43
|
+
2. The user approves with their passkey (signs in, or creates a wallet first if new)
|
|
44
|
+
3. The popup posts the result back to your page and closes itself
|
|
45
|
+
4. The returned promise resolves with the result
|
|
95
46
|
|
|
96
|
-
|
|
97
|
-
const result = orbi.handleSignCallback();
|
|
98
|
-
if (!result) return; // user cancelled or came directly to this page
|
|
99
|
-
|
|
100
|
-
const { opId } = await orbi.bundle({
|
|
101
|
-
walletAddress: result.walletAddress,
|
|
102
|
-
quoteId: result.quoteId,
|
|
103
|
-
signedAuthEntryXdr: result.signedAuthEntryXdr,
|
|
104
|
-
contractId: 'YOUR_CONTRACT_ID',
|
|
105
|
-
functionName: 'transfer',
|
|
106
|
-
argsXdr: result.argsXdr,
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Wait for on-chain confirmation via SSE
|
|
110
|
-
const status = await orbi.waitForConfirmation(opId);
|
|
111
|
-
if (status.status === 'confirmed') {
|
|
112
|
-
console.log('tx hash:', status.txHash);
|
|
113
|
-
}
|
|
114
|
-
```
|
|
47
|
+
The connected wallet is cached in `localStorage`, so later `connect()` calls resolve instantly without reopening the popup. Call `disconnect()` to clear it.
|
|
115
48
|
|
|
116
49
|
---
|
|
117
50
|
|
|
118
|
-
## API
|
|
51
|
+
## API
|
|
119
52
|
|
|
120
|
-
### `new OrbiClient(config)`
|
|
53
|
+
### `new OrbiClient(config?)`
|
|
121
54
|
|
|
122
|
-
|
|
|
55
|
+
| Option | Type | Default | Description |
|
|
123
56
|
|---|---|---|---|
|
|
124
|
-
| `
|
|
125
|
-
| `apiKey` | `string` | No | Your developer API key. Enables gas sponsorship. |
|
|
126
|
-
|
|
127
|
-
---
|
|
128
|
-
|
|
129
|
-
### Wallet Connection
|
|
130
|
-
|
|
131
|
-
#### `connect(params)`
|
|
132
|
-
|
|
133
|
-
Redirects the user to Orbi to connect their wallet.
|
|
134
|
-
|
|
135
|
-
```ts
|
|
136
|
-
orbi.connect({ redirectUrl: 'https://yourapp.com/callback' });
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
#### `handleCallback()`
|
|
140
|
-
|
|
141
|
-
Call on your callback page after `connect()` redirects back. Returns wallet data or `null` if no token in URL.
|
|
142
|
-
|
|
143
|
-
```ts
|
|
144
|
-
const wallet = await orbi.handleCallback();
|
|
145
|
-
// { walletAddress: string, passkeyId: string, email: string } | null
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
### Transaction Signing
|
|
151
|
-
|
|
152
|
-
#### `sign(params)`
|
|
153
|
-
|
|
154
|
-
Redirects the user to Orbi to approve a transaction with their passkey.
|
|
155
|
-
|
|
156
|
-
```ts
|
|
157
|
-
orbi.sign({
|
|
158
|
-
walletAddress: string,
|
|
159
|
-
contractId: string,
|
|
160
|
-
functionName: string,
|
|
161
|
-
argsXdr: string[], // XDR-encoded Soroban args
|
|
162
|
-
redirectUrl: string,
|
|
163
|
-
});
|
|
164
|
-
```
|
|
57
|
+
| `network` | `'testnet' \| 'mainnet'` | `'testnet'` | Stellar network — passed through so Orbi shows the right network badge and validates the transaction against the matching ledger |
|
|
165
58
|
|
|
166
|
-
|
|
59
|
+
### `connect(): Promise<ConnectedWallet>`
|
|
167
60
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
Call on your sign-callback page. Returns the signed data needed to call `bundle()`, or `null` if nothing to process.
|
|
171
|
-
|
|
172
|
-
```ts
|
|
173
|
-
const result = orbi.handleSignCallback();
|
|
174
|
-
// { signedAuthEntryXdr, quoteId, argsXdr, nativeSacId, walletAddress } | null
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
|
-
### Relay
|
|
180
|
-
|
|
181
|
-
#### `bundle(params)`
|
|
182
|
-
|
|
183
|
-
Submit a signed operation to the Orbi relay for on-chain execution.
|
|
184
|
-
|
|
185
|
-
```ts
|
|
186
|
-
const { opId } = await orbi.bundle({
|
|
187
|
-
walletAddress: string,
|
|
188
|
-
quoteId: string,
|
|
189
|
-
signedAuthEntryXdr: string,
|
|
190
|
-
contractId: string,
|
|
191
|
-
functionName: string,
|
|
192
|
-
argsXdr: string[],
|
|
193
|
-
});
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
#### `waitForConfirmation(opId)`
|
|
197
|
-
|
|
198
|
-
Wait for the operation to be confirmed or fail. Uses SSE — resolves in ~5s on Stellar.
|
|
199
|
-
|
|
200
|
-
```ts
|
|
201
|
-
const status = await orbi.waitForConfirmation(opId);
|
|
202
|
-
// { opId, status: 'confirmed' | 'failed', txHash: string | null, error: string | null }
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
#### `getStatus(opId)`
|
|
206
|
-
|
|
207
|
-
One-shot status check (non-blocking alternative to `waitForConfirmation`).
|
|
208
|
-
|
|
209
|
-
```ts
|
|
210
|
-
const status = await orbi.getStatus(opId);
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
---
|
|
214
|
-
|
|
215
|
-
### Token Management
|
|
216
|
-
|
|
217
|
-
#### `watchAsset(params)`
|
|
218
|
-
|
|
219
|
-
Redirect the user to add a Soroban token to their Orbi wallet.
|
|
220
|
-
|
|
221
|
-
```ts
|
|
222
|
-
orbi.watchAsset({
|
|
223
|
-
contractId: 'TOKEN_CONTRACT_ID',
|
|
224
|
-
redirectUrl: 'https://yourapp.com/callback',
|
|
225
|
-
});
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
#### `handleWatchAssetCallback()`
|
|
229
|
-
|
|
230
|
-
Call on your callback page after `watchAsset()` redirects back.
|
|
61
|
+
Connects the user's wallet. Returns a cached session instantly if one exists; otherwise opens the connect popup and resolves once the user approves.
|
|
231
62
|
|
|
232
63
|
```ts
|
|
233
|
-
const
|
|
234
|
-
// { contractId: string, added: boolean } | null
|
|
64
|
+
const { walletAddress, credentialId, passkeyId } = await orbi.connect();
|
|
235
65
|
```
|
|
236
66
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
### Gas Sponsorship (Developer Setup)
|
|
240
|
-
|
|
241
|
-
These methods are for onboarding your dApp to gas sponsorship. You can also do this through the [developer portal](https://developers.orbiwallet.xyz).
|
|
67
|
+
### `signTransaction({ xdr, walletAddress? }): Promise<SignResult>`
|
|
242
68
|
|
|
243
|
-
|
|
69
|
+
Opens the sign popup so the user can review and approve a transaction with their passkey.
|
|
244
70
|
|
|
245
|
-
|
|
71
|
+
- `xdr` — base64-encoded `TransactionEnvelope` XDR for a classic G account (build it with `@stellar/stellar-sdk`)
|
|
72
|
+
- `walletAddress` — optional; defaults to the currently connected address
|
|
246
73
|
|
|
247
74
|
```ts
|
|
248
|
-
const {
|
|
249
|
-
developerName: 'My App',
|
|
250
|
-
email: 'you@example.com',
|
|
251
|
-
});
|
|
75
|
+
const { signedXdr, walletAddress } = await orbi.signTransaction({ xdr });
|
|
252
76
|
```
|
|
253
77
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
Set the Stellar G... address that will fund gas for your users. Requires `apiKey` in constructor.
|
|
257
|
-
|
|
258
|
-
```ts
|
|
259
|
-
await orbi.setDeployer('GABC...XYZ');
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
#### `getDeployerBalance()`
|
|
263
|
-
|
|
264
|
-
Check your gas tank balance. Requires `apiKey` in constructor.
|
|
265
|
-
|
|
266
|
-
```ts
|
|
267
|
-
const { balanceXlm } = await orbi.getDeployerBalance();
|
|
268
|
-
console.log(`${balanceXlm} XLM remaining`);
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
---
|
|
78
|
+
Orbi only signs — it does not submit. Submit `signedXdr` to Horizon yourself.
|
|
272
79
|
|
|
273
|
-
|
|
80
|
+
### `getAddress(): string | null`
|
|
274
81
|
|
|
275
|
-
|
|
82
|
+
Returns the cached wallet address from a previous `connect()`, or `null` if not connected.
|
|
276
83
|
|
|
277
|
-
|
|
278
|
-
2. **Create a Stellar keypair** for your gas tank (a regular G... account)
|
|
279
|
-
3. **Fund it with XLM** — each sponsored transaction deducts the exact network fee
|
|
280
|
-
4. **Set the deployer** in the developer portal (or via `setDeployer()`)
|
|
281
|
-
5. **Add `apiKey`** to your `OrbiClient` constructor
|
|
84
|
+
### `disconnect(): void`
|
|
282
85
|
|
|
283
|
-
|
|
86
|
+
Clears the cached session on your side. Doesn't revoke anything on Orbi — the user can reconnect any time with their passkey.
|
|
284
87
|
|
|
285
88
|
---
|
|
286
89
|
|
|
287
90
|
## Notes
|
|
288
91
|
|
|
289
|
-
-
|
|
290
|
-
-
|
|
291
|
-
-
|
|
292
|
-
- XDR arg encoding: use `@stellar/stellar-sdk` to build and encode Soroban contract args
|
|
92
|
+
- Requires popups to be allowed for your site — `connect()`/`signTransaction()` reject with a clear error if the popup is blocked or the user closes it
|
|
93
|
+
- Works with Orbi G-wallets only (classic Stellar accounts)
|
|
94
|
+
- Results are only ever accepted from `https://keys.orbiwallet.xyz`, verified by both message origin and source window — never trust `postMessage` from elsewhere
|
|
293
95
|
|
|
294
96
|
---
|
|
295
97
|
|
|
296
98
|
## Links
|
|
297
99
|
|
|
298
100
|
- [Orbi Wallet](https://orbiwallet.xyz)
|
|
299
|
-
- [Developer Portal](https://developers.orbiwallet.xyz)
|
|
300
|
-
- [npm](https://npmjs.com/package/@orbi-wallet/sdk)
|
|
301
101
|
- [GitHub](https://github.com/Novablitz404/orbi-smart-wallet)
|
|
302
102
|
|
|
303
103
|
---
|
package/dist/client.d.ts
CHANGED
|
@@ -1,106 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @orbi-wallet/sdk — Orbi Smart Wallet SDK
|
|
2
|
+
* @orbi-wallet/sdk — Orbi Smart Wallet SDK (G-wallet)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Connects a Stellar dApp to Orbi passkey wallets via a popup + postMessage
|
|
5
|
+
* handshake — the same integration pattern Coinbase Smart Wallet uses.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* const
|
|
9
|
-
*
|
|
10
|
-
* Quick start (dApp sponsors gas):
|
|
11
|
-
* const orbi = new OrbiClient({
|
|
12
|
-
* apiUrl: 'https://api.orbiwallet.xyz',
|
|
13
|
-
* apiKey: 'YOUR_API_KEY', // <-- enables gasless
|
|
14
|
-
* });
|
|
15
|
-
*
|
|
16
|
-
* Flow:
|
|
17
|
-
* 1. orbi.connect({ redirectUrl }) — redirect user to connect wallet
|
|
18
|
-
* 2. orbi.handleCallback() — on return, exchange token for wallet data
|
|
19
|
-
* 3. orbi.sign({ ..., redirectUrl }) — redirect user to approve transaction
|
|
20
|
-
* 4. orbi.handleSignCallback() → bundle() — on return, submit signed tx
|
|
21
|
-
* 5. orbi.waitForConfirmation(opId) — wait for on-chain confirmation
|
|
7
|
+
* const orbi = new OrbiClient();
|
|
8
|
+
* const { walletAddress } = await orbi.connect();
|
|
9
|
+
* const { signedXdr } = await orbi.signTransaction({ xdr });
|
|
22
10
|
*/
|
|
23
|
-
import type {
|
|
11
|
+
import type { ConnectedWallet, OrbiClientConfig, SignResult } from './types';
|
|
24
12
|
export declare class OrbiClient {
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}): void;
|
|
33
|
-
/**
|
|
34
|
-
* Clear the Orbi session and redirect back to your app.
|
|
35
|
-
* Call this when the user disconnects — clears the passkey session on
|
|
36
|
-
* keys.orbiwallet.xyz so the next connect() prompts for authentication again.
|
|
37
|
-
* You are responsible for clearing your own local wallet state before calling this.
|
|
38
|
-
*/
|
|
39
|
-
disconnect(redirectUrl: string): void;
|
|
40
|
-
/** Call this on your callback page after orbi.connect() redirects back. */
|
|
41
|
-
handleCallback(): Promise<{
|
|
42
|
-
walletAddress: string;
|
|
43
|
-
passkeyId: string;
|
|
44
|
-
email: string;
|
|
45
|
-
} | null>;
|
|
13
|
+
private network;
|
|
14
|
+
constructor(config?: OrbiClientConfig);
|
|
15
|
+
/** Wallet address from a previous `connect()`, restored from local storage. */
|
|
16
|
+
getAddress(): string | null;
|
|
17
|
+
/** Forget the cached session. The next `connect()` reopens the Orbi popup. */
|
|
18
|
+
disconnect(): void;
|
|
19
|
+
private getSession;
|
|
46
20
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
21
|
+
* Connect the user's Orbi wallet. Resolves immediately from a cached
|
|
22
|
+
* session if one exists; otherwise opens the Orbi connect popup and
|
|
23
|
+
* resolves once the user approves.
|
|
49
24
|
*/
|
|
50
|
-
|
|
51
|
-
walletAddress: string;
|
|
52
|
-
contractId: string;
|
|
53
|
-
functionName: string;
|
|
54
|
-
argsXdr: string[];
|
|
55
|
-
redirectUrl: string;
|
|
56
|
-
}): void;
|
|
57
|
-
/** Call this on your sign-callback page after orbi.sign() redirects back. */
|
|
58
|
-
handleSignCallback(): {
|
|
59
|
-
signedAuthEntryXdr: string;
|
|
60
|
-
quoteId: string;
|
|
61
|
-
argsXdr: string[];
|
|
62
|
-
nativeSacId: string;
|
|
63
|
-
walletAddress: string;
|
|
64
|
-
} | null;
|
|
65
|
-
/** Redirect the user to add a token to their Orbi wallet. */
|
|
66
|
-
watchAsset(params: {
|
|
67
|
-
contractId: string;
|
|
68
|
-
redirectUrl: string;
|
|
69
|
-
}): void;
|
|
70
|
-
/** Call this on your callback page after orbi.watchAsset() redirects back. */
|
|
71
|
-
handleWatchAssetCallback(): {
|
|
72
|
-
contractId: string;
|
|
73
|
-
added: boolean;
|
|
74
|
-
} | null;
|
|
25
|
+
connect(): Promise<ConnectedWallet>;
|
|
75
26
|
/**
|
|
76
|
-
*
|
|
77
|
-
*
|
|
27
|
+
* Ask the user to review and approve a transaction with their passkey.
|
|
28
|
+
*
|
|
29
|
+
* `xdr` is a base64-encoded TransactionEnvelope for a classic G account —
|
|
30
|
+
* build it with `@stellar/stellar-sdk` on your end. Orbi only signs; submit
|
|
31
|
+
* the returned `signedXdr` to Horizon yourself.
|
|
78
32
|
*/
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
functionName: string;
|
|
85
|
-
argsXdr: string[];
|
|
86
|
-
}): Promise<{
|
|
87
|
-
opId: string;
|
|
88
|
-
}>;
|
|
89
|
-
/** One-shot status check for an operation. */
|
|
90
|
-
getStatus(opId: string): Promise<OpStatus>;
|
|
91
|
-
/** Wait for confirmed or failed via SSE (~5s on Stellar). */
|
|
92
|
-
waitForConfirmation(opId: string): Promise<OpStatus>;
|
|
93
|
-
/** Register a new developer account. Returns a one-time API key — save it. */
|
|
94
|
-
register(params: {
|
|
95
|
-
developerName: string;
|
|
96
|
-
email: string;
|
|
97
|
-
deployerPublicKey?: string;
|
|
98
|
-
}): Promise<{
|
|
99
|
-
apiKey: string;
|
|
100
|
-
message: string;
|
|
101
|
-
}>;
|
|
102
|
-
/** Set or update the deployer (gas tank) address for this API key. */
|
|
103
|
-
setDeployer(deployerPublicKey: string): Promise<void>;
|
|
104
|
-
/** Check the XLM balance of your gas tank. */
|
|
105
|
-
getDeployerBalance(): Promise<DeployerBalance>;
|
|
33
|
+
signTransaction(params: {
|
|
34
|
+
xdr: string;
|
|
35
|
+
walletAddress?: string;
|
|
36
|
+
}): Promise<SignResult>;
|
|
37
|
+
private openPopup;
|
|
106
38
|
}
|
package/dist/client.js
CHANGED
|
@@ -1,248 +1,142 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* @orbi-wallet/sdk — Orbi Smart Wallet SDK
|
|
3
|
+
* @orbi-wallet/sdk — Orbi Smart Wallet SDK (G-wallet)
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Connects a Stellar dApp to Orbi passkey wallets via a popup + postMessage
|
|
6
|
+
* handshake — the same integration pattern Coinbase Smart Wallet uses.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* const
|
|
10
|
-
*
|
|
11
|
-
* Quick start (dApp sponsors gas):
|
|
12
|
-
* const orbi = new OrbiClient({
|
|
13
|
-
* apiUrl: 'https://api.orbiwallet.xyz',
|
|
14
|
-
* apiKey: 'YOUR_API_KEY', // <-- enables gasless
|
|
15
|
-
* });
|
|
16
|
-
*
|
|
17
|
-
* Flow:
|
|
18
|
-
* 1. orbi.connect({ redirectUrl }) — redirect user to connect wallet
|
|
19
|
-
* 2. orbi.handleCallback() — on return, exchange token for wallet data
|
|
20
|
-
* 3. orbi.sign({ ..., redirectUrl }) — redirect user to approve transaction
|
|
21
|
-
* 4. orbi.handleSignCallback() → bundle() — on return, submit signed tx
|
|
22
|
-
* 5. orbi.waitForConfirmation(opId) — wait for on-chain confirmation
|
|
8
|
+
* const orbi = new OrbiClient();
|
|
9
|
+
* const { walletAddress } = await orbi.connect();
|
|
10
|
+
* const { signedXdr } = await orbi.signTransaction({ xdr });
|
|
23
11
|
*/
|
|
24
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
13
|
exports.OrbiClient = void 0;
|
|
14
|
+
// Generated from package.json at build time (see scripts/generate-version.js)
|
|
15
|
+
// — package.json stays the single source of truth for name/version.
|
|
16
|
+
const version_1 = require("./version");
|
|
26
17
|
const KEYS_URL = 'https://keys.orbiwallet.xyz';
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
function def(p, n, fn) {
|
|
32
|
-
if (typeof p[n] !== 'function')
|
|
33
|
-
Object.defineProperty(p, n, { value: fn, writable: true, configurable: true });
|
|
34
|
-
}
|
|
35
|
-
function patch(p) {
|
|
36
|
-
if (!p)
|
|
37
|
-
return;
|
|
38
|
-
def(p, 'readBigInt64BE', function (o = 0) { return dv(this).getBigInt64(o, false); });
|
|
39
|
-
def(p, 'readBigUInt64BE', function (o = 0) { return dv(this).getBigUint64(o, false); });
|
|
40
|
-
def(p, 'readBigInt64LE', function (o = 0) { return dv(this).getBigInt64(o, true); });
|
|
41
|
-
def(p, 'readBigUInt64LE', function (o = 0) { return dv(this).getBigUint64(o, true); });
|
|
42
|
-
def(p, 'writeBigInt64BE', function (v, o = 0) { dv(this).setBigInt64(o, v, false); return o + 8; });
|
|
43
|
-
def(p, 'writeBigUInt64BE', function (v, o = 0) { dv(this).setBigUint64(o, v, false); return o + 8; });
|
|
44
|
-
def(p, 'writeBigInt64LE', function (v, o = 0) { dv(this).setBigInt64(o, v, true); return o + 8; });
|
|
45
|
-
def(p, 'writeBigUInt64LE', function (v, o = 0) { dv(this).setBigUint64(o, v, true); return o + 8; });
|
|
46
|
-
}
|
|
47
|
-
patch(Uint8Array.prototype);
|
|
48
|
-
patch(globalThis.Buffer?.prototype);
|
|
49
|
-
}
|
|
18
|
+
const KEYS_ORIGIN = new URL(KEYS_URL).origin;
|
|
19
|
+
const SESSION_KEY = 'orbi_session';
|
|
20
|
+
const POPUP_WIDTH = 420;
|
|
21
|
+
const POPUP_HEIGHT = 640;
|
|
50
22
|
class OrbiClient {
|
|
51
|
-
constructor(config) {
|
|
52
|
-
this.
|
|
53
|
-
this.apiKey = config.apiKey;
|
|
54
|
-
_patchBuffer();
|
|
23
|
+
constructor(config = {}) {
|
|
24
|
+
this.network = config.network ?? 'testnet';
|
|
55
25
|
}
|
|
56
|
-
|
|
57
|
-
|
|
26
|
+
// ── Session ─────────────────────────────────────────────────────────────────
|
|
27
|
+
/** Wallet address from a previous `connect()`, restored from local storage. */
|
|
28
|
+
getAddress() {
|
|
29
|
+
return this.getSession()?.walletAddress ?? null;
|
|
58
30
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
url.searchParams.set('origin', window.location.origin);
|
|
65
|
-
window.location.href = url.toString();
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Clear the Orbi session and redirect back to your app.
|
|
69
|
-
* Call this when the user disconnects — clears the passkey session on
|
|
70
|
-
* keys.orbiwallet.xyz so the next connect() prompts for authentication again.
|
|
71
|
-
* You are responsible for clearing your own local wallet state before calling this.
|
|
72
|
-
*/
|
|
73
|
-
disconnect(redirectUrl) {
|
|
74
|
-
const url = new URL(`${KEYS_URL}/signout`);
|
|
75
|
-
url.searchParams.set('redirect', redirectUrl);
|
|
76
|
-
window.location.href = url.toString();
|
|
31
|
+
/** Forget the cached session. The next `connect()` reopens the Orbi popup. */
|
|
32
|
+
disconnect() {
|
|
33
|
+
if (typeof window === 'undefined')
|
|
34
|
+
return;
|
|
35
|
+
localStorage.removeItem(SESSION_KEY);
|
|
77
36
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const params = new URLSearchParams(window.location.search);
|
|
81
|
-
const token = params.get('token');
|
|
82
|
-
if (!token)
|
|
37
|
+
getSession() {
|
|
38
|
+
if (typeof window === 'undefined')
|
|
83
39
|
return null;
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
throw new Error('Invalid or expired Orbi token');
|
|
87
|
-
return res.json();
|
|
40
|
+
const raw = localStorage.getItem(SESSION_KEY);
|
|
41
|
+
return raw ? JSON.parse(raw) : null;
|
|
88
42
|
}
|
|
89
|
-
// ──
|
|
43
|
+
// ── Wallet connection ───────────────────────────────────────────────────────
|
|
90
44
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
45
|
+
* Connect the user's Orbi wallet. Resolves immediately from a cached
|
|
46
|
+
* session if one exists; otherwise opens the Orbi connect popup and
|
|
47
|
+
* resolves once the user approves.
|
|
93
48
|
*/
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const signedXdr = params.get('signedXdr');
|
|
110
|
-
const quoteId = params.get('quoteId');
|
|
111
|
-
const argsXdrRaw = params.get('argsXdr');
|
|
112
|
-
const nativeSacId = params.get('nativeSacId');
|
|
113
|
-
const walletAddress = params.get('walletAddress');
|
|
114
|
-
if (!signedXdr || !quoteId || !argsXdrRaw || !nativeSacId || !walletAddress)
|
|
115
|
-
return null;
|
|
116
|
-
return {
|
|
117
|
-
signedAuthEntryXdr: signedXdr,
|
|
118
|
-
quoteId,
|
|
119
|
-
argsXdr: JSON.parse(argsXdrRaw),
|
|
120
|
-
nativeSacId,
|
|
121
|
-
walletAddress,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
// ── Token management ────────────────────────────────────────────────────────
|
|
125
|
-
/** Redirect the user to add a token to their Orbi wallet. */
|
|
126
|
-
watchAsset(params) {
|
|
127
|
-
const url = new URL(`${KEYS_URL}/watch-asset`);
|
|
128
|
-
url.searchParams.set('contractId', params.contractId);
|
|
129
|
-
url.searchParams.set('redirect', params.redirectUrl);
|
|
130
|
-
url.searchParams.set('origin', window.location.origin);
|
|
131
|
-
window.location.href = url.toString();
|
|
132
|
-
}
|
|
133
|
-
/** Call this on your callback page after orbi.watchAsset() redirects back. */
|
|
134
|
-
handleWatchAssetCallback() {
|
|
135
|
-
const params = new URLSearchParams(window.location.search);
|
|
136
|
-
const contractId = params.get('watchedContractId');
|
|
137
|
-
if (!contractId)
|
|
138
|
-
return null;
|
|
139
|
-
return { contractId, added: params.get('watched') === 'true' };
|
|
49
|
+
async connect() {
|
|
50
|
+
const cached = this.getSession();
|
|
51
|
+
if (cached)
|
|
52
|
+
return cached;
|
|
53
|
+
const wallet = await this.openPopup({
|
|
54
|
+
path: '/connect',
|
|
55
|
+
successType: 'orbi_connected',
|
|
56
|
+
mapSuccess: (msg) => ({
|
|
57
|
+
walletAddress: msg.address,
|
|
58
|
+
credentialId: msg.credentialId ?? '',
|
|
59
|
+
passkeyId: msg.passkeyId ?? '',
|
|
60
|
+
}),
|
|
61
|
+
});
|
|
62
|
+
localStorage.setItem(SESSION_KEY, JSON.stringify(wallet));
|
|
63
|
+
return wallet;
|
|
140
64
|
}
|
|
141
|
-
// ──
|
|
65
|
+
// ── Transaction signing ─────────────────────────────────────────────────────
|
|
142
66
|
/**
|
|
143
|
-
*
|
|
144
|
-
*
|
|
67
|
+
* Ask the user to review and approve a transaction with their passkey.
|
|
68
|
+
*
|
|
69
|
+
* `xdr` is a base64-encoded TransactionEnvelope for a classic G account —
|
|
70
|
+
* build it with `@stellar/stellar-sdk` on your end. Orbi only signs; submit
|
|
71
|
+
* the returned `signedXdr` to Horizon yourself.
|
|
145
72
|
*/
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
73
|
+
signTransaction(params) {
|
|
74
|
+
const walletAddress = params.walletAddress ?? this.getAddress() ?? undefined;
|
|
75
|
+
return this.openPopup({
|
|
76
|
+
path: '/sign',
|
|
77
|
+
params: {
|
|
78
|
+
xdr: params.xdr,
|
|
79
|
+
network: this.network,
|
|
80
|
+
...(walletAddress ? { walletAddress } : {}),
|
|
152
81
|
},
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
call: {
|
|
158
|
-
contractId: params.contractId,
|
|
159
|
-
function: params.functionName,
|
|
160
|
-
argsXdr: params.argsXdr,
|
|
161
|
-
},
|
|
82
|
+
successType: 'orbi_g_signed',
|
|
83
|
+
mapSuccess: (msg) => ({
|
|
84
|
+
signedXdr: msg.signedXdr,
|
|
85
|
+
walletAddress: msg.walletAddress,
|
|
162
86
|
}),
|
|
163
87
|
});
|
|
164
|
-
if (!res.ok) {
|
|
165
|
-
const err = await res.json().catch(() => ({}));
|
|
166
|
-
throw new Error(err.error ?? `Bundle failed: ${res.status}`);
|
|
167
|
-
}
|
|
168
|
-
return res.json();
|
|
169
88
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
89
|
+
// ── Popup + postMessage handshake ───────────────────────────────────────────
|
|
90
|
+
openPopup(req) {
|
|
91
|
+
if (typeof window === 'undefined') {
|
|
92
|
+
return Promise.reject(new Error('Orbi requires a browser environment'));
|
|
93
|
+
}
|
|
94
|
+
const url = new URL(`${KEYS_URL}${req.path}`);
|
|
95
|
+
url.searchParams.set('origin', window.location.origin);
|
|
96
|
+
url.searchParams.set('sdkName', version_1.SDK_NAME);
|
|
97
|
+
url.searchParams.set('sdkVersion', version_1.SDK_VERSION);
|
|
98
|
+
for (const [key, value] of Object.entries(req.params ?? {}))
|
|
99
|
+
url.searchParams.set(key, value);
|
|
100
|
+
const left = window.screenX + Math.max(0, (window.outerWidth - POPUP_WIDTH) / 2);
|
|
101
|
+
const top = window.screenY + Math.max(0, (window.outerHeight - POPUP_HEIGHT) / 2);
|
|
102
|
+
const popup = window.open(url.toString(), 'orbi-wallet', `width=${POPUP_WIDTH},height=${POPUP_HEIGHT},left=${left},top=${top}`);
|
|
103
|
+
if (!popup) {
|
|
104
|
+
return Promise.reject(new Error('Popup blocked — allow popups for this site to use Orbi'));
|
|
105
|
+
}
|
|
179
106
|
return new Promise((resolve, reject) => {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
107
|
+
let settled = false;
|
|
108
|
+
const settle = (fn) => {
|
|
109
|
+
if (settled)
|
|
110
|
+
return;
|
|
111
|
+
settled = true;
|
|
112
|
+
window.removeEventListener('message', onMessage);
|
|
113
|
+
clearInterval(closedCheck);
|
|
114
|
+
fn();
|
|
115
|
+
};
|
|
116
|
+
const onMessage = (event) => {
|
|
117
|
+
// event.origin is never affected by Cross-Origin-Opener-Policy and
|
|
118
|
+
// can't be spoofed — always required. event.source (the popup window
|
|
119
|
+
// reference) adds extra anti-spoofing when the browser provides it,
|
|
120
|
+
// but COOP isolation can null it out on either side, so we only
|
|
121
|
+
// enforce it when present rather than rejecting legit messages.
|
|
122
|
+
if (event.origin !== KEYS_ORIGIN)
|
|
123
|
+
return;
|
|
124
|
+
if (event.source !== null && event.source !== popup)
|
|
125
|
+
return;
|
|
126
|
+
const data = event.data;
|
|
127
|
+
if (data?.type === req.successType) {
|
|
128
|
+
settle(() => resolve(req.mapSuccess(data)));
|
|
194
129
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
reject(new Error('Invalid SSE response'));
|
|
130
|
+
else if (data?.type === 'orbi_cancelled') {
|
|
131
|
+
settle(() => reject(new Error('Cancelled in Orbi')));
|
|
198
132
|
}
|
|
199
133
|
};
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
// ── Gas sponsorship onboarding ──────────────────────────────────────────────
|
|
207
|
-
/** Register a new developer account. Returns a one-time API key — save it. */
|
|
208
|
-
async register(params) {
|
|
209
|
-
const res = await fetch(`${this.apiUrl}/v1/account/register`, {
|
|
210
|
-
method: 'POST',
|
|
211
|
-
headers: { 'Content-Type': 'application/json' },
|
|
212
|
-
body: JSON.stringify(params),
|
|
213
|
-
});
|
|
214
|
-
if (!res.ok) {
|
|
215
|
-
const err = await res.json().catch(() => ({}));
|
|
216
|
-
throw new Error(err.error ?? `Registration failed: ${res.status}`);
|
|
217
|
-
}
|
|
218
|
-
return res.json();
|
|
219
|
-
}
|
|
220
|
-
/** Set or update the deployer (gas tank) address for this API key. */
|
|
221
|
-
async setDeployer(deployerPublicKey) {
|
|
222
|
-
if (!this.apiKey)
|
|
223
|
-
throw new Error('apiKey required — pass it in the OrbiClient constructor');
|
|
224
|
-
const res = await fetch(`${this.apiUrl}/v1/account/deployer`, {
|
|
225
|
-
method: 'PATCH',
|
|
226
|
-
headers: { 'Content-Type': 'application/json', ...this.authHeaders() },
|
|
227
|
-
body: JSON.stringify({ deployerPublicKey }),
|
|
134
|
+
const closedCheck = setInterval(() => {
|
|
135
|
+
if (popup.closed)
|
|
136
|
+
settle(() => reject(new Error('Orbi window closed before completing')));
|
|
137
|
+
}, 500);
|
|
138
|
+
window.addEventListener('message', onMessage);
|
|
228
139
|
});
|
|
229
|
-
if (!res.ok) {
|
|
230
|
-
const err = await res.json().catch(() => ({}));
|
|
231
|
-
throw new Error(err.error ?? `Set deployer failed: ${res.status}`);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
/** Check the XLM balance of your gas tank. */
|
|
235
|
-
async getDeployerBalance() {
|
|
236
|
-
if (!this.apiKey)
|
|
237
|
-
throw new Error('apiKey required — pass it in the OrbiClient constructor');
|
|
238
|
-
const res = await fetch(`${this.apiUrl}/v1/account/balance`, {
|
|
239
|
-
headers: this.authHeaders(),
|
|
240
|
-
});
|
|
241
|
-
if (!res.ok) {
|
|
242
|
-
const err = await res.json().catch(() => ({}));
|
|
243
|
-
throw new Error(err.error ?? `Balance fetch failed: ${res.status}`);
|
|
244
|
-
}
|
|
245
|
-
return res.json();
|
|
246
140
|
}
|
|
247
141
|
}
|
|
248
142
|
exports.OrbiClient = OrbiClient;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
export { OrbiClient } from './client';
|
|
2
|
-
export {
|
|
3
|
-
export type { OrbiClientConfig, QuoteResult, BundleResult, OpStatus, OrbiNetwork, DeployerBalance } from './types';
|
|
2
|
+
export type { ConnectedWallet, OrbiClientConfig, OrbiNetwork, SignResult } from './types';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.OrbiClient = void 0;
|
|
4
4
|
var client_1 = require("./client");
|
|
5
5
|
Object.defineProperty(exports, "OrbiClient", { enumerable: true, get: function () { return client_1.OrbiClient; } });
|
|
6
|
-
var wallet_1 = require("./wallet");
|
|
7
|
-
Object.defineProperty(exports, "deriveWalletAddress", { enumerable: true, get: function () { return wallet_1.deriveWalletAddress; } });
|
package/dist/types.d.ts
CHANGED
|
@@ -1,32 +1,14 @@
|
|
|
1
1
|
export type OrbiNetwork = 'testnet' | 'mainnet';
|
|
2
2
|
export interface OrbiClientConfig {
|
|
3
|
-
/**
|
|
4
|
-
apiUrl: string;
|
|
5
|
-
/** Optional: your API key if required by the relay */
|
|
6
|
-
apiKey?: string;
|
|
3
|
+
/** Stellar network the dApp is operating on. Defaults to 'testnet'. */
|
|
7
4
|
network?: OrbiNetwork;
|
|
8
5
|
}
|
|
9
|
-
export interface
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
expiresAtLedger: number;
|
|
14
|
-
currentLedger: number;
|
|
15
|
-
nativeSacId: string;
|
|
16
|
-
feeCollectorAddress: string;
|
|
17
|
-
authEntryXdr: string;
|
|
6
|
+
export interface ConnectedWallet {
|
|
7
|
+
walletAddress: string;
|
|
8
|
+
credentialId: string;
|
|
9
|
+
passkeyId: string;
|
|
18
10
|
}
|
|
19
|
-
export interface
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
export interface OpStatus {
|
|
23
|
-
opId: string;
|
|
24
|
-
status: 'pending' | 'batched' | 'confirmed' | 'failed';
|
|
25
|
-
txHash: string | null;
|
|
26
|
-
error: string | null;
|
|
27
|
-
}
|
|
28
|
-
export interface DeployerBalance {
|
|
29
|
-
address: string;
|
|
30
|
-
balanceXlm: string;
|
|
31
|
-
balanceStroops: string;
|
|
11
|
+
export interface SignResult {
|
|
12
|
+
signedXdr: string;
|
|
13
|
+
walletAddress: string;
|
|
32
14
|
}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SDK_VERSION = exports.SDK_NAME = void 0;
|
|
4
|
+
// Generated by scripts/generate-version.js from package.json — do not edit.
|
|
5
|
+
exports.SDK_NAME = "@orbi-wallet/sdk";
|
|
6
|
+
exports.SDK_VERSION = "0.1.0";
|
package/package.json
CHANGED
|
@@ -1,32 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orbi-wallet/sdk",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "Orbi Smart Wallet SDK — connect any dApp to Orbi passkey wallets
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Orbi Smart Wallet SDK — connect any Stellar dApp to Orbi passkey wallets",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
8
10
|
"license": "MIT",
|
|
9
|
-
"keywords": [
|
|
11
|
+
"keywords": [
|
|
12
|
+
"stellar",
|
|
13
|
+
"wallet",
|
|
14
|
+
"passkey",
|
|
15
|
+
"sdk"
|
|
16
|
+
],
|
|
10
17
|
"homepage": "https://orbiwallet.xyz",
|
|
11
18
|
"repository": {
|
|
12
19
|
"type": "git",
|
|
13
|
-
"url": "https://github.com/Novablitz404/orbi-
|
|
20
|
+
"url": "git+https://github.com/Novablitz404/orbi-wallet-sdk.git"
|
|
14
21
|
},
|
|
15
22
|
"bugs": {
|
|
16
|
-
"url": "https://github.com/Novablitz404/orbi-
|
|
23
|
+
"url": "https://github.com/Novablitz404/orbi-wallet-sdk/issues"
|
|
17
24
|
},
|
|
18
25
|
"scripts": {
|
|
26
|
+
"prebuild": "node scripts/generate-version.js",
|
|
19
27
|
"build": "tsc",
|
|
28
|
+
"predev": "node scripts/generate-version.js",
|
|
20
29
|
"dev": "tsc --watch"
|
|
21
30
|
},
|
|
22
|
-
"dependencies": {
|
|
23
|
-
"@stellar/stellar-sdk": "^15.1.0"
|
|
24
|
-
},
|
|
25
31
|
"devDependencies": {
|
|
26
32
|
"@types/node": "^20.14.2",
|
|
27
33
|
"typescript": "^5.5.2"
|
|
28
|
-
},
|
|
29
|
-
"peerDependencies": {
|
|
30
|
-
"@stellar/stellar-sdk": "^15.1.0"
|
|
31
34
|
}
|
|
32
35
|
}
|
package/dist/wallet.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export type OrbiNetwork = 'testnet' | 'mainnet';
|
|
2
|
-
/**
|
|
3
|
-
* Derive the deterministic wallet C-address for a passkey ID.
|
|
4
|
-
*
|
|
5
|
-
* Matches the relay's deriveWalletAddress — same formula:
|
|
6
|
-
* salt = sha256(passkey_id)
|
|
7
|
-
* address = sha256(networkId + deployer_G_address + salt)
|
|
8
|
-
*
|
|
9
|
-
* Call this immediately after passkey creation to show the user their
|
|
10
|
-
* address — no transaction or network call needed.
|
|
11
|
-
*/
|
|
12
|
-
export declare function deriveWalletAddress(params: {
|
|
13
|
-
passkeyId: Uint8Array;
|
|
14
|
-
deployerPublicKey: string;
|
|
15
|
-
network?: OrbiNetwork;
|
|
16
|
-
}): string;
|
package/dist/wallet.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deriveWalletAddress = deriveWalletAddress;
|
|
4
|
-
const stellar_sdk_1 = require("@stellar/stellar-sdk");
|
|
5
|
-
const PASSPHRASES = {
|
|
6
|
-
testnet: stellar_sdk_1.Networks.TESTNET,
|
|
7
|
-
mainnet: stellar_sdk_1.Networks.PUBLIC,
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* Derive the deterministic wallet C-address for a passkey ID.
|
|
11
|
-
*
|
|
12
|
-
* Matches the relay's deriveWalletAddress — same formula:
|
|
13
|
-
* salt = sha256(passkey_id)
|
|
14
|
-
* address = sha256(networkId + deployer_G_address + salt)
|
|
15
|
-
*
|
|
16
|
-
* Call this immediately after passkey creation to show the user their
|
|
17
|
-
* address — no transaction or network call needed.
|
|
18
|
-
*/
|
|
19
|
-
function deriveWalletAddress(params) {
|
|
20
|
-
const { passkeyId, deployerPublicKey, network = 'testnet' } = params;
|
|
21
|
-
const networkPassphrase = PASSPHRASES[network];
|
|
22
|
-
const salt = (0, stellar_sdk_1.hash)(Buffer.from(passkeyId));
|
|
23
|
-
const networkId = (0, stellar_sdk_1.hash)(Buffer.from(networkPassphrase));
|
|
24
|
-
const preimage = stellar_sdk_1.xdr.HashIdPreimage.envelopeTypeContractId(new stellar_sdk_1.xdr.HashIdPreimageContractId({
|
|
25
|
-
networkId: Buffer.from(networkId),
|
|
26
|
-
contractIdPreimage: stellar_sdk_1.xdr.ContractIdPreimage.contractIdPreimageFromAddress(new stellar_sdk_1.xdr.ContractIdPreimageFromAddress({
|
|
27
|
-
address: new stellar_sdk_1.Address(deployerPublicKey).toScAddress(),
|
|
28
|
-
salt: Buffer.from(salt),
|
|
29
|
-
})),
|
|
30
|
-
}));
|
|
31
|
-
const contractId = (0, stellar_sdk_1.hash)(preimage.toXDR());
|
|
32
|
-
return stellar_sdk_1.StrKey.encodeContract(contractId);
|
|
33
|
-
}
|