@novasamatech/host-api-wrapper 0.7.9-5
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 +429 -0
- package/dist/accounts.d.ts +93 -0
- package/dist/accounts.js +263 -0
- package/dist/chat.d.ts +33 -0
- package/dist/chat.js +125 -0
- package/dist/constants.d.ts +11 -0
- package/dist/constants.js +12 -0
- package/dist/deriveEntropy.d.ts +3 -0
- package/dist/deriveEntropy.js +8 -0
- package/dist/helpers.d.ts +9 -0
- package/dist/helpers.js +19 -0
- package/dist/hostApi.d.ts +1 -0
- package/dist/hostApi.js +3 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +16 -0
- package/dist/injectWeb3.d.ts +90 -0
- package/dist/injectWeb3.js +157 -0
- package/dist/localStorage.d.ts +18 -0
- package/dist/localStorage.js +44 -0
- package/dist/metaProvider.d.ts +7 -0
- package/dist/metaProvider.js +24 -0
- package/dist/notification.d.ts +15 -0
- package/dist/notification.js +20 -0
- package/dist/papiProvider.d.ts +7 -0
- package/dist/papiProvider.js +349 -0
- package/dist/payments.d.ts +35 -0
- package/dist/payments.js +49 -0
- package/dist/permission.d.ts +24 -0
- package/dist/permission.js +28 -0
- package/dist/preimage.d.ts +9 -0
- package/dist/preimage.js +24 -0
- package/dist/sandboxTransport.d.ts +9 -0
- package/dist/sandboxTransport.js +109 -0
- package/dist/statementStore.d.ts +44 -0
- package/dist/statementStore.js +41 -0
- package/dist/theme.d.ts +6 -0
- package/dist/theme.js +18 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
# @novasamatech/host-api-wrapper
|
|
2
|
+
|
|
3
|
+
An easy way to embed Polkadot host functionality into your dapp.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Product SDK provides a set of tools to integrate your application with any Polkadot host application.
|
|
8
|
+
Core features:
|
|
9
|
+
- Generic injectWeb3 provider similar to [polkadot-js extension](https://polkadot.js.org/extension/)
|
|
10
|
+
- Chat module integration
|
|
11
|
+
- Statement store integration
|
|
12
|
+
- Accounts provider for product accounts and signing
|
|
13
|
+
- Redirect [PAPI](https://papi.how/) requests to host application
|
|
14
|
+
- Receive additional information from host application - supported chains, theme, etc.
|
|
15
|
+
- Local storage for persisting data in the host application
|
|
16
|
+
- Preimage manager for looking up and submitting preimages
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```shell
|
|
21
|
+
npm install @novasamatech/host-api-wrapper --save -E
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
### Injecting account provider into `injectedWeb3` interface
|
|
27
|
+
|
|
28
|
+
Product SDK can provide account information and signers with the same interface as any other Polkadot-compatible wallet.
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { injectSpektrExtension, SpektrExtensionName } from '@novasamatech/host-api-wrapper';
|
|
32
|
+
import { connectInjectedExtension, type InjectedPolkadotAccount } from '@polkadot-api/pjs-signer';
|
|
33
|
+
|
|
34
|
+
async function getSpektrExtension() {
|
|
35
|
+
const ready = await injectSpektrExtension();
|
|
36
|
+
|
|
37
|
+
if (ready) {
|
|
38
|
+
return connectInjectedExtension(SpektrExtensionName)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function getAccounts(): Promise<InjectedPolkadotAccount[]> {
|
|
45
|
+
const extension = await getSpektrExtension();
|
|
46
|
+
|
|
47
|
+
if (extension) {
|
|
48
|
+
return extension.getAccounts()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// fallback to other providers
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Redirecting PAPI requests to host application
|
|
57
|
+
|
|
58
|
+
You can wrap your PAPI provider with Spektr provider to support redirecting requests to the host application.
|
|
59
|
+
|
|
60
|
+
```diff
|
|
61
|
+
import { createClient, type PolkadotClient } from 'polkadot-api';
|
|
62
|
+
import { getWsProvider } from 'polkadot-api/ws-provider';
|
|
63
|
+
import { createPapiProvider, WellKnownChain } from '@novasamatech/host-api-wrapper';
|
|
64
|
+
|
|
65
|
+
function createPapiClient(): PolkadotClient {
|
|
66
|
+
const polkadotEndpoint = 'wss://...';
|
|
67
|
+
|
|
68
|
+
- const provider = getWsProvider(polkadotEndpoint);
|
|
69
|
+
+ const provider = createPapiProvider({
|
|
70
|
+
+ chainId: WellKnownChain.polkadotRelay,
|
|
71
|
+
+ fallback: getWsProvider(polkadotEndpoint),
|
|
72
|
+
+ });
|
|
73
|
+
|
|
74
|
+
return createClient(provider);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Subscribing host connection status
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { metaProvider } from '@novasamatech/host-api-wrapper';
|
|
82
|
+
|
|
83
|
+
const unsubscribe = metaProvider.subscribeConnectionStatus((status) => {
|
|
84
|
+
console.log('connection status changed', status);
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Chat Integration
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { createProductChatManager } from '@novasamatech/host-api-wrapper';
|
|
92
|
+
|
|
93
|
+
// Create manager instance
|
|
94
|
+
const chat = createProductChatManager();
|
|
95
|
+
|
|
96
|
+
// Register your product as a chat contact
|
|
97
|
+
const roomRegistrationStatus = await chat.registerRoom({
|
|
98
|
+
roomId: 'my-product-room',
|
|
99
|
+
name: 'My Product',
|
|
100
|
+
icon: 'https://example.com/icon.png'
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Register your product as a chat bot
|
|
104
|
+
const botRegistrationStatus = await chat.registerBot({
|
|
105
|
+
botId: 'my-product-bot',
|
|
106
|
+
name: 'My Product',
|
|
107
|
+
icon: 'https://example.com/icon.png'
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Send a message
|
|
111
|
+
const { messageId } = await chat.sendMessage('my-product-room', {
|
|
112
|
+
tag: 'Text',
|
|
113
|
+
value: 'Hello dear user!'
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Subscribing to chat actions (incoming messages, etc.)
|
|
117
|
+
const subscriber = chat.subscribeAction((action) => {
|
|
118
|
+
console.log('Room:', action.roomId);
|
|
119
|
+
console.log('Sender:', action.peer);
|
|
120
|
+
|
|
121
|
+
const payload = action.payload;
|
|
122
|
+
|
|
123
|
+
if (payload.tag === 'MessagePosted') {
|
|
124
|
+
console.log('Received message:', action.value);
|
|
125
|
+
}
|
|
126
|
+
if (payload.tag === 'ActionTriggered') {
|
|
127
|
+
console.log('User triggered action:', action.value)
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Subscribing to chat room list updates
|
|
132
|
+
const chatListSubscriber = chat.subscribeChatList((rooms) => {
|
|
133
|
+
console.log('Chat rooms updated:', rooms);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Sending a custom message
|
|
137
|
+
await chat.sendMessage('my-product-room', {
|
|
138
|
+
tag: 'Custom',
|
|
139
|
+
value: { messageType: 'my-custom-type', payload: new Uint8Array([/* ... */]) }
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// Handling custom message rendering requests from host
|
|
143
|
+
const unsubscribeRenderer = chat.onCustomMessageRenderingRequest((messageType, payload, render) => {
|
|
144
|
+
// Build a CustomRendererNode tree and pass it to render()
|
|
145
|
+
render({
|
|
146
|
+
tag: 'Text',
|
|
147
|
+
value: {
|
|
148
|
+
modifiers: undefined,
|
|
149
|
+
props: { style: undefined, color: undefined },
|
|
150
|
+
children: [{ tag: 'String', value: 'Custom message content' }],
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
return () => {
|
|
155
|
+
// cleanup when subscription ends
|
|
156
|
+
};
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Note:** Messages sent before registration will be queued and sent automatically after successful registration.
|
|
161
|
+
|
|
162
|
+
### Statement Store
|
|
163
|
+
|
|
164
|
+
The Statement Store provides a decentralized way to store statements (messages).
|
|
165
|
+
It can be used for various purposes like p2p communication, storing temp data, etc.
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import { createStatementStore } from '@novasamatech/host-api-wrapper';
|
|
169
|
+
import type { Topic, Statement, SignedStatement, StatementTopicFilter } from '@novasamatech/host-api-wrapper';
|
|
170
|
+
|
|
171
|
+
// Create statement store instance
|
|
172
|
+
const statementStore = createStatementStore();
|
|
173
|
+
|
|
174
|
+
// Define topics (32-byte identifiers) to categorize statements
|
|
175
|
+
const topic: Topic = new Uint8Array(32);
|
|
176
|
+
|
|
177
|
+
// Subscribe to statements matching ALL listed topics (AND semantics)
|
|
178
|
+
const filter: StatementTopicFilter = { matchAll: [topic] };
|
|
179
|
+
const subscription = statementStore.subscribe(filter, (page) => {
|
|
180
|
+
// page.isComplete is true once the initial historical dump is done
|
|
181
|
+
console.log('Received statements:', page.statements, 'synced:', page.isComplete);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Create a proof for a new statement
|
|
185
|
+
const accountId = ['product.dot', 0]; // [DotNS identifier, derivation index]
|
|
186
|
+
const statement: Statement = {
|
|
187
|
+
proof: undefined,
|
|
188
|
+
decryptionKey: undefined,
|
|
189
|
+
priority: undefined,
|
|
190
|
+
channel: undefined,
|
|
191
|
+
topics: [topic],
|
|
192
|
+
data: new Uint8Array([/* your data */]),
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const proof = await statementStore.createProof(accountId, statement);
|
|
196
|
+
|
|
197
|
+
// Submit a signed statement
|
|
198
|
+
const signedStatement: SignedStatement = {
|
|
199
|
+
...statement,
|
|
200
|
+
proof,
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
await statementStore.submit(signedStatement);
|
|
204
|
+
|
|
205
|
+
// Unsubscribe when done
|
|
206
|
+
subscription.unsubscribe();
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Accounts Provider
|
|
210
|
+
|
|
211
|
+
The Accounts Provider allows you to access product accounts and create signers for signing transactions.
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
import { accounts } from '@novasamatech/host-api-wrapper';
|
|
215
|
+
import type { ProductAccount } from '@novasamatech/host-api-wrapper';
|
|
216
|
+
|
|
217
|
+
// Get the user's primary DotNS username (RFC-0014)
|
|
218
|
+
// — prompts for permission on first call
|
|
219
|
+
const userIdResult = await accounts.getUserId();
|
|
220
|
+
|
|
221
|
+
if (userIdResult.isOk()) {
|
|
222
|
+
const { primaryUsername } = userIdResult.value;
|
|
223
|
+
console.log('Primary username:', primaryUsername);
|
|
224
|
+
} else {
|
|
225
|
+
const err = userIdResult.error;
|
|
226
|
+
if (err.tag === 'NotConnected') {
|
|
227
|
+
console.log('User is not logged in');
|
|
228
|
+
} else if (err.tag === 'PermissionDenied') {
|
|
229
|
+
console.log('User denied disclosure of their primary username');
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Request login — triggers host sign-in UI; reason is shown to the user
|
|
234
|
+
const loginResult = await accounts.requestLogin('Sign in to access your account');
|
|
235
|
+
|
|
236
|
+
if (loginResult.isOk()) {
|
|
237
|
+
const outcome = loginResult.value; // 'success' | 'alreadyConnected' | 'rejected'
|
|
238
|
+
if (outcome === 'rejected') {
|
|
239
|
+
console.log('User cancelled login');
|
|
240
|
+
}
|
|
241
|
+
} else {
|
|
242
|
+
console.error('Login error:', loginResult.error);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Get a product account by DotNS identifier and derivation index
|
|
246
|
+
const accountResult = await accounts.getProductAccount('product.dot', 0);
|
|
247
|
+
|
|
248
|
+
if (accountResult.isOk()) {
|
|
249
|
+
const account: ProductAccount = accountResult.value;
|
|
250
|
+
console.log('Public key:', account.publicKey);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Get account alias
|
|
254
|
+
const aliasResult = await accounts.getProductAccountAlias('product.dot', 0);
|
|
255
|
+
|
|
256
|
+
if (aliasResult.isOk()) {
|
|
257
|
+
console.log('Alias:', aliasResult.value);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Get legacy accounts (external wallets)
|
|
261
|
+
const legacyAccountsResult = await accounts.getLegacyAccounts();
|
|
262
|
+
|
|
263
|
+
if (legacyAccountsResult.isOk()) {
|
|
264
|
+
console.log('Legacy accounts:', legacyAccountsResult.value);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Subscribe to account connection status changes
|
|
268
|
+
const unsubscribe = accounts.subscribeAccountConnectionStatus((status) => {
|
|
269
|
+
// status: 'connected' | 'disconnected'
|
|
270
|
+
console.log('Account connection status:', status);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// Create a signer for a product account (for use with PAPI).
|
|
274
|
+
// Resolve the account first, then hand it to the signer factory.
|
|
275
|
+
const productAccountResult = await accounts.getProductAccount('product.dot', 0);
|
|
276
|
+
|
|
277
|
+
if (productAccountResult.isOk()) {
|
|
278
|
+
const productSigner = accounts.getProductAccountSigner(productAccountResult.value);
|
|
279
|
+
const signedTx = await tx.signAndSubmit(productSigner);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Create a signer for a legacy account.
|
|
283
|
+
// Fetch the legacy account list, pick one, then pass it to the signer factory.
|
|
284
|
+
const legacyAccountsResult = await accounts.getLegacyAccounts();
|
|
285
|
+
|
|
286
|
+
if (legacyAccountsResult.isOk()) {
|
|
287
|
+
const [legacyAccount] = legacyAccountsResult.value;
|
|
288
|
+
if (legacyAccount) {
|
|
289
|
+
const legacySigner = accounts.getLegacyAccountSigner(legacyAccount);
|
|
290
|
+
const signedTx = await tx.signAndSubmit(legacySigner);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
> If you need a non-default transport (e.g. for tests or multi-host setups), use `createAccountsProvider(transport)` to build your own instance with the same API.
|
|
296
|
+
|
|
297
|
+
### Local Storage
|
|
298
|
+
|
|
299
|
+
The Local Storage module provides a way to persist data in the host application's storage.
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
import { hostLocalStorage, createLocalStorage } from '@novasamatech/host-api-wrapper';
|
|
303
|
+
|
|
304
|
+
// Use the default instance
|
|
305
|
+
const storage = hostLocalStorage;
|
|
306
|
+
|
|
307
|
+
// Or create a custom instance with a different transport
|
|
308
|
+
// const storage = createLocalStorage(customTransport);
|
|
309
|
+
|
|
310
|
+
// Write and read raw bytes
|
|
311
|
+
await storage.writeBytes('key', new Uint8Array([1, 2, 3]));
|
|
312
|
+
const bytes = await storage.readBytes('key');
|
|
313
|
+
|
|
314
|
+
// Write and read strings
|
|
315
|
+
await storage.writeString('greeting', 'Hello, World!');
|
|
316
|
+
const greeting = await storage.readString('greeting');
|
|
317
|
+
|
|
318
|
+
// Write and read JSON
|
|
319
|
+
await storage.writeJSON('config', { theme: 'dark', fontSize: 14 });
|
|
320
|
+
const config = await storage.readJSON('config');
|
|
321
|
+
|
|
322
|
+
// Clear a key
|
|
323
|
+
await storage.clear('key');
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Derive Entropy
|
|
327
|
+
|
|
328
|
+
The Derive Entropy function allows products to derive deterministic 32-byte entropy scoped to the product and a caller-chosen key.
|
|
329
|
+
|
|
330
|
+
```ts
|
|
331
|
+
import { deriveEntropy } from '@novasamatech/host-api-wrapper';
|
|
332
|
+
|
|
333
|
+
const result = await deriveEntropy(new Uint8Array([1, 2, 3]));
|
|
334
|
+
|
|
335
|
+
if (result.isOk()) {
|
|
336
|
+
const entropy: Uint8Array = result.value;
|
|
337
|
+
console.log('Derived entropy:', entropy);
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Permissions
|
|
342
|
+
|
|
343
|
+
Products can request device and remote permissions from the host. Decisions are prompted once and persisted permanently — subsequent calls for the same permission resolve immediately without prompting.
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
import { requestDevicePermission, requestPermission } from '@novasamatech/host-api-wrapper';
|
|
347
|
+
|
|
348
|
+
// Request a single device permission
|
|
349
|
+
const deviceResult = await requestDevicePermission('Camera');
|
|
350
|
+
if (deviceResult.isOk()) {
|
|
351
|
+
console.log('Camera granted:', deviceResult.value); // boolean
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Request remote permissions in a batch (single user prompt for all)
|
|
355
|
+
const remoteResult = await requestPermission([
|
|
356
|
+
{ tag: 'Remote', value: ['api.coingecko.com', '*.example.com'] },
|
|
357
|
+
{ tag: 'ChainSubmit', value: undefined },
|
|
358
|
+
]);
|
|
359
|
+
if (remoteResult.isOk()) {
|
|
360
|
+
console.log('All remote permissions granted:', remoteResult.value); // boolean
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Available device permission values: `'Notifications'`, `'Camera'`, `'Microphone'`, `'Bluetooth'`, `'NFC'`, `'Location'`, `'Clipboard'`, `'OpenUrl'`, `'Biometrics'`.
|
|
365
|
+
|
|
366
|
+
Available remote permission tags: `'Remote'` (HTTP/WS domain patterns), `'WebRTC'`, `'ChainSubmit'`, `'PreimageSubmit'`, `'StatementSubmit'`.
|
|
367
|
+
|
|
368
|
+
> **Note:** `remote_chain_transaction_broadcast`, `remote_preimage_submit`, and `remote_statement_store_submit` implicitly trigger a permission prompt if the relevant permission has not yet been resolved. Call `requestPermission(...)` proactively before entering those flows for a controlled UX.
|
|
369
|
+
|
|
370
|
+
### Preimage Manager
|
|
371
|
+
|
|
372
|
+
The Preimage Manager allows you to lookup and submit preimages to the host application.
|
|
373
|
+
|
|
374
|
+
```ts
|
|
375
|
+
import { preimageManager, createPreimageManager } from '@novasamatech/host-api-wrapper';
|
|
376
|
+
|
|
377
|
+
// Use the default instance
|
|
378
|
+
const manager = preimageManager;
|
|
379
|
+
|
|
380
|
+
// Or create a custom instance with a different transport
|
|
381
|
+
// const manager = createPreimageManager(customTransport);
|
|
382
|
+
|
|
383
|
+
// Lookup a preimage by its hash key
|
|
384
|
+
const subscription = manager.lookup('0x1234...', (preimage) => {
|
|
385
|
+
if (preimage) {
|
|
386
|
+
console.log('Preimage found:', preimage);
|
|
387
|
+
} else {
|
|
388
|
+
console.log('Preimage not found');
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// Unsubscribe when done
|
|
393
|
+
subscription.unsubscribe();
|
|
394
|
+
|
|
395
|
+
// Submit a preimage
|
|
396
|
+
const preimageKey = await manager.submit(new Uint8Array([1, 2, 3, 4]));
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Payment manager
|
|
400
|
+
|
|
401
|
+
```ts
|
|
402
|
+
import { createPaymentManager } from '@novasamatech/host-api-wrapper';
|
|
403
|
+
|
|
404
|
+
const payments = createPaymentManager();
|
|
405
|
+
|
|
406
|
+
// Subscribe to the user's payment balance (host will prompt for consent)
|
|
407
|
+
const balanceSub = payments.subscribeBalance(balance => {
|
|
408
|
+
console.log('Available:', balance.available);
|
|
409
|
+
console.log('Pending:', balance.pending);
|
|
410
|
+
});
|
|
411
|
+
balanceSub.onInterrupt(() => console.log('Balance access denied or lost'));
|
|
412
|
+
|
|
413
|
+
// Top up the user's balance from a product account
|
|
414
|
+
await payments.topUp(1_000_000n, {
|
|
415
|
+
type: 'productAccount',
|
|
416
|
+
dotNsIdentifier: 'my-product.dot',
|
|
417
|
+
derivationIndex: 0,
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
// Request a payment from the user (host shows confirmation UI)
|
|
421
|
+
const destination = new Uint8Array(32); // 32-byte AccountId
|
|
422
|
+
const receipt = await payments.requestPayment(500_000n, destination);
|
|
423
|
+
|
|
424
|
+
// Track payment settlement
|
|
425
|
+
const statusSub = payments.subscribePaymentStatus(receipt.id, status => {
|
|
426
|
+
if (status.type === 'completed') console.log('Payment settled');
|
|
427
|
+
if (status.type === 'failed') console.log('Payment failed:', status.reason);
|
|
428
|
+
});
|
|
429
|
+
```
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { AccountConnectionStatus as AccountConnectionStatusCodec, CodecType, LegacyAccount as LegacyAccountCodec, ProductAccountId as ProductAccountIdCodec, Subscription, Transport } from '@novasamatech/host-api';
|
|
2
|
+
import { RingLocation } from '@novasamatech/host-api';
|
|
3
|
+
import type { PolkadotSigner } from 'polkadot-api';
|
|
4
|
+
export type ProductAccountId = CodecType<typeof ProductAccountIdCodec>;
|
|
5
|
+
export type ProductAccount = {
|
|
6
|
+
dotNsIdentifier: string;
|
|
7
|
+
derivationIndex: number;
|
|
8
|
+
publicKey: Uint8Array;
|
|
9
|
+
};
|
|
10
|
+
export type LegacyAccount = CodecType<typeof LegacyAccountCodec>;
|
|
11
|
+
export type AccountConnectionStatus = CodecType<typeof AccountConnectionStatusCodec>;
|
|
12
|
+
export declare const createAccountsProvider: (transport?: Transport) => {
|
|
13
|
+
getUserId(): import("neverthrow").ResultAsync<{
|
|
14
|
+
primaryUsername: string;
|
|
15
|
+
}, import("@novasamatech/scale").CodecError<undefined, "GetUserIdErr::NotConnected"> | import("@novasamatech/scale").CodecError<{
|
|
16
|
+
reason: string;
|
|
17
|
+
}, "GetUserIdErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "GetUserIdErr::PermissionDenied">>;
|
|
18
|
+
requestLogin(reason?: string): import("neverthrow").ResultAsync<"success" | "alreadyConnected" | "rejected", import("@novasamatech/scale").CodecError<{
|
|
19
|
+
reason: string;
|
|
20
|
+
}, "LoginErr::Unknown">>;
|
|
21
|
+
getProductAccount(dotNsIdentifier: string, derivationIndex?: number): import("neverthrow").ResultAsync<{
|
|
22
|
+
publicKey: Uint8Array<ArrayBufferLike>;
|
|
23
|
+
dotNsIdentifier: string;
|
|
24
|
+
derivationIndex: number;
|
|
25
|
+
}, import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::NotConnected"> | import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::Rejected"> | import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::DomainNotValid"> | import("@novasamatech/scale").CodecError<{
|
|
26
|
+
reason: string;
|
|
27
|
+
}, "RequestCredentialsErr::Unknown">>;
|
|
28
|
+
getProductAccountAlias(dotNsIdentifier: string, derivationIndex?: number): import("neverthrow").ResultAsync<{
|
|
29
|
+
context: Uint8Array<ArrayBufferLike>;
|
|
30
|
+
alias: Uint8Array<ArrayBufferLike>;
|
|
31
|
+
}, import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::NotConnected"> | import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::Rejected"> | import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::DomainNotValid"> | import("@novasamatech/scale").CodecError<{
|
|
32
|
+
reason: string;
|
|
33
|
+
}, "RequestCredentialsErr::Unknown">>;
|
|
34
|
+
getLegacyAccounts(): import("neverthrow").ResultAsync<{
|
|
35
|
+
publicKey: Uint8Array<ArrayBufferLike>;
|
|
36
|
+
name: string | undefined;
|
|
37
|
+
}[], import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::NotConnected"> | import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::Rejected"> | import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::DomainNotValid"> | import("@novasamatech/scale").CodecError<{
|
|
38
|
+
reason: string;
|
|
39
|
+
}, "RequestCredentialsErr::Unknown">>;
|
|
40
|
+
createRingVRFProof(dotNsIdentifier: string, derivationIndex: number | undefined, location: CodecType<typeof RingLocation>, message: Uint8Array): import("neverthrow").ResultAsync<Uint8Array<ArrayBufferLike>, import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::Rejected"> | import("@novasamatech/scale").CodecError<{
|
|
41
|
+
reason: string;
|
|
42
|
+
}, "CreateProofErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::RingNotFound">>;
|
|
43
|
+
/**
|
|
44
|
+
* Builds a `PolkadotSigner` that delegates to the host via `host_create_transaction`.
|
|
45
|
+
*
|
|
46
|
+
* The factory is async because `PolkadotSigner.publicKey` must be a synchronous
|
|
47
|
+
* `Uint8Array` on the returned object — it is fetched up front via `host_account_get`.
|
|
48
|
+
*/
|
|
49
|
+
getProductAccountSigner(account: ProductAccount, signerType?: "signPayload" | "createTransaction"): PolkadotSigner;
|
|
50
|
+
subscribeAccountConnectionStatus(callback: (status: AccountConnectionStatus) => void): Subscription<void>;
|
|
51
|
+
getLegacyAccountSigner(account: LegacyAccount): PolkadotSigner;
|
|
52
|
+
};
|
|
53
|
+
export declare const accounts: {
|
|
54
|
+
getUserId(): import("neverthrow").ResultAsync<{
|
|
55
|
+
primaryUsername: string;
|
|
56
|
+
}, import("@novasamatech/scale").CodecError<undefined, "GetUserIdErr::NotConnected"> | import("@novasamatech/scale").CodecError<{
|
|
57
|
+
reason: string;
|
|
58
|
+
}, "GetUserIdErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "GetUserIdErr::PermissionDenied">>;
|
|
59
|
+
requestLogin(reason?: string): import("neverthrow").ResultAsync<"success" | "alreadyConnected" | "rejected", import("@novasamatech/scale").CodecError<{
|
|
60
|
+
reason: string;
|
|
61
|
+
}, "LoginErr::Unknown">>;
|
|
62
|
+
getProductAccount(dotNsIdentifier: string, derivationIndex?: number): import("neverthrow").ResultAsync<{
|
|
63
|
+
publicKey: Uint8Array<ArrayBufferLike>;
|
|
64
|
+
dotNsIdentifier: string;
|
|
65
|
+
derivationIndex: number;
|
|
66
|
+
}, import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::NotConnected"> | import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::Rejected"> | import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::DomainNotValid"> | import("@novasamatech/scale").CodecError<{
|
|
67
|
+
reason: string;
|
|
68
|
+
}, "RequestCredentialsErr::Unknown">>;
|
|
69
|
+
getProductAccountAlias(dotNsIdentifier: string, derivationIndex?: number): import("neverthrow").ResultAsync<{
|
|
70
|
+
context: Uint8Array<ArrayBufferLike>;
|
|
71
|
+
alias: Uint8Array<ArrayBufferLike>;
|
|
72
|
+
}, import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::NotConnected"> | import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::Rejected"> | import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::DomainNotValid"> | import("@novasamatech/scale").CodecError<{
|
|
73
|
+
reason: string;
|
|
74
|
+
}, "RequestCredentialsErr::Unknown">>;
|
|
75
|
+
getLegacyAccounts(): import("neverthrow").ResultAsync<{
|
|
76
|
+
publicKey: Uint8Array<ArrayBufferLike>;
|
|
77
|
+
name: string | undefined;
|
|
78
|
+
}[], import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::NotConnected"> | import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::Rejected"> | import("@novasamatech/scale").CodecError<undefined, "RequestCredentialsErr::DomainNotValid"> | import("@novasamatech/scale").CodecError<{
|
|
79
|
+
reason: string;
|
|
80
|
+
}, "RequestCredentialsErr::Unknown">>;
|
|
81
|
+
createRingVRFProof(dotNsIdentifier: string, derivationIndex: number | undefined, location: CodecType<typeof RingLocation>, message: Uint8Array): import("neverthrow").ResultAsync<Uint8Array<ArrayBufferLike>, import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::Rejected"> | import("@novasamatech/scale").CodecError<{
|
|
82
|
+
reason: string;
|
|
83
|
+
}, "CreateProofErr::Unknown"> | import("@novasamatech/scale").CodecError<undefined, "CreateProofErr::RingNotFound">>;
|
|
84
|
+
/**
|
|
85
|
+
* Builds a `PolkadotSigner` that delegates to the host via `host_create_transaction`.
|
|
86
|
+
*
|
|
87
|
+
* The factory is async because `PolkadotSigner.publicKey` must be a synchronous
|
|
88
|
+
* `Uint8Array` on the returned object — it is fetched up front via `host_account_get`.
|
|
89
|
+
*/
|
|
90
|
+
getProductAccountSigner(account: ProductAccount, signerType?: "signPayload" | "createTransaction"): PolkadotSigner;
|
|
91
|
+
subscribeAccountConnectionStatus(callback: (status: AccountConnectionStatus) => void): Subscription<void>;
|
|
92
|
+
getLegacyAccountSigner(account: LegacyAccount): PolkadotSigner;
|
|
93
|
+
};
|