@novasamatech/host-api-wrapper 0.9.4 → 0.10.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 +45 -0
- package/dist/coinPayment.d.ts +35 -0
- package/dist/coinPayment.js +67 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/localStorage.d.ts +7 -0
- package/dist/localStorage.js +22 -0
- package/dist/papiProvider.js +3 -1
- package/dist/worker.d.ts +9 -0
- package/dist/worker.js +22 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -402,6 +402,17 @@ const config = await storage.readJSON('config');
|
|
|
402
402
|
|
|
403
403
|
// Clear a key
|
|
404
404
|
await storage.clear('key');
|
|
405
|
+
|
|
406
|
+
// Subscribe to a key. The callback fires with the current value right away,
|
|
407
|
+
// then on every later write or clear. `undefined` means the key is absent.
|
|
408
|
+
const sub = storage.subscribeBytes('key', (bytes) => {
|
|
409
|
+
console.log('key changed:', bytes);
|
|
410
|
+
});
|
|
411
|
+
storage.subscribeString('greeting', (text) => console.log(text));
|
|
412
|
+
storage.subscribeJSON('config', (value) => console.log(value));
|
|
413
|
+
|
|
414
|
+
// Stop receiving updates
|
|
415
|
+
sub.unsubscribe();
|
|
405
416
|
```
|
|
406
417
|
|
|
407
418
|
### Derive Entropy
|
|
@@ -509,3 +520,37 @@ const statusSub = payments.subscribePaymentStatus(receipt.id, status => {
|
|
|
509
520
|
if (status.type === 'failed') console.log('Payment failed:', status.reason);
|
|
510
521
|
});
|
|
511
522
|
```
|
|
523
|
+
|
|
524
|
+
### Coin payment (RFC 0017)
|
|
525
|
+
|
|
526
|
+
Firewalled purses, cheques, and receivables. The long-running operations
|
|
527
|
+
(rebalance, delete, deposit, refund, listen) stream clearing status through a
|
|
528
|
+
callback and return a `Subscription`; `onInterrupt` fires with a
|
|
529
|
+
`CoinPaymentErr` if the host tears the stream down.
|
|
530
|
+
|
|
531
|
+
```ts
|
|
532
|
+
import { createCoinPayment } from '@novasamatech/host-api-wrapper';
|
|
533
|
+
|
|
534
|
+
const coinPayment = createCoinPayment();
|
|
535
|
+
|
|
536
|
+
// Create a purse and read it back
|
|
537
|
+
const purse = await coinPayment.createPurse('Terminal purse');
|
|
538
|
+
const info = await coinPayment.queryPurse(purse);
|
|
539
|
+
console.log('balance:', info.balance);
|
|
540
|
+
|
|
541
|
+
// Pay a receivable with a cheque
|
|
542
|
+
const receivable = await coinPayment.createReceivable(purse);
|
|
543
|
+
const cheque = await coinPayment.createCheque(purse, receivable, 1000);
|
|
544
|
+
|
|
545
|
+
// Claim the cheque, watching the coins clear
|
|
546
|
+
const sub = coinPayment.deposit(cheque, status => {
|
|
547
|
+
if (status.tag === 'Done') console.log('cleared:', status.value.cleared);
|
|
548
|
+
if (status.tag === 'Failed') console.log('failed:', status.value.error);
|
|
549
|
+
});
|
|
550
|
+
sub.onInterrupt(err => console.log('deposit interrupted:', err));
|
|
551
|
+
|
|
552
|
+
// Wait for a cheque delivered over a standard channel
|
|
553
|
+
coinPayment.listenForPayment(receivable, item => {
|
|
554
|
+
if (item.tag === 'Cheque') console.log('received cheque:', item.value.amount);
|
|
555
|
+
});
|
|
556
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { CodecType, CoinPaymentCheque, CoinPaymentErr, CoinPaymentListenForItem, CoinPaymentPurseInfo, CoinPaymentStatus, HexString, Subscription, Transport } from '@novasamatech/host-api';
|
|
2
|
+
/** Purse identifier (RFC 0017). `0xffffffff` is the well-known main purse. */
|
|
3
|
+
export type PurseId = number;
|
|
4
|
+
/** Receivable public key, as a 0x-prefixed 32-byte hex string. */
|
|
5
|
+
export type Receivable = HexString;
|
|
6
|
+
export type PurseInfo = CodecType<typeof CoinPaymentPurseInfo>;
|
|
7
|
+
export type Cheque = CodecType<typeof CoinPaymentCheque>;
|
|
8
|
+
/** Clearing status streamed by rebalance, delete, deposit, and refund. */
|
|
9
|
+
export type ClearingStatus = CodecType<typeof CoinPaymentStatus>;
|
|
10
|
+
/** Item streamed by `listenForPayment`: a delivery channel, then the cheque. */
|
|
11
|
+
export type PaymentDelivery = CodecType<typeof CoinPaymentListenForItem>;
|
|
12
|
+
type CoinPaymentInterrupt = CodecType<typeof CoinPaymentErr>;
|
|
13
|
+
export declare const createCoinPayment: (transport?: Transport) => {
|
|
14
|
+
createPurse(name: string): Promise<PurseId>;
|
|
15
|
+
queryPurse(purse: PurseId): Promise<PurseInfo>;
|
|
16
|
+
createReceivable(into: PurseId): Promise<Receivable>;
|
|
17
|
+
createCheque(from: PurseId, to: Receivable, amount: number): Promise<Cheque>;
|
|
18
|
+
rebalancePurse(from: PurseId, to: PurseId, amount: number, onStatus: (status: ClearingStatus) => void): Subscription<CoinPaymentInterrupt>;
|
|
19
|
+
deletePurse(target: PurseId, drainInto: PurseId, onStatus: (status: ClearingStatus) => void): Subscription<CoinPaymentInterrupt>;
|
|
20
|
+
deposit(cheque: Cheque, onStatus: (status: ClearingStatus) => void): Subscription<CoinPaymentInterrupt>;
|
|
21
|
+
refund(receivable: Receivable, onStatus: (status: ClearingStatus) => void): Subscription<CoinPaymentInterrupt>;
|
|
22
|
+
listenForPayment(receivable: Receivable, onDelivery: (item: PaymentDelivery) => void): Subscription<CoinPaymentInterrupt>;
|
|
23
|
+
};
|
|
24
|
+
export declare const hostCoinPayment: {
|
|
25
|
+
createPurse(name: string): Promise<PurseId>;
|
|
26
|
+
queryPurse(purse: PurseId): Promise<PurseInfo>;
|
|
27
|
+
createReceivable(into: PurseId): Promise<Receivable>;
|
|
28
|
+
createCheque(from: PurseId, to: Receivable, amount: number): Promise<Cheque>;
|
|
29
|
+
rebalancePurse(from: PurseId, to: PurseId, amount: number, onStatus: (status: ClearingStatus) => void): Subscription<CoinPaymentInterrupt>;
|
|
30
|
+
deletePurse(target: PurseId, drainInto: PurseId, onStatus: (status: ClearingStatus) => void): Subscription<CoinPaymentInterrupt>;
|
|
31
|
+
deposit(cheque: Cheque, onStatus: (status: ClearingStatus) => void): Subscription<CoinPaymentInterrupt>;
|
|
32
|
+
refund(receivable: Receivable, onStatus: (status: ClearingStatus) => void): Subscription<CoinPaymentInterrupt>;
|
|
33
|
+
listenForPayment(receivable: Receivable, onDelivery: (item: PaymentDelivery) => void): Subscription<CoinPaymentInterrupt>;
|
|
34
|
+
};
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { createHostApi, enumValue } from '@novasamatech/host-api';
|
|
2
|
+
import { resultToPromise, unwrapVersionedResult } from './helpers.js';
|
|
3
|
+
import { sandboxTransport } from './sandboxTransport.js';
|
|
4
|
+
export const createCoinPayment = (transport = sandboxTransport) => {
|
|
5
|
+
const hostApi = createHostApi(transport);
|
|
6
|
+
const version = 'v1';
|
|
7
|
+
function stream(subscriber) {
|
|
8
|
+
return {
|
|
9
|
+
unsubscribe: subscriber.unsubscribe,
|
|
10
|
+
onInterrupt: cb => subscriber.onInterrupt(v => cb(v.value)),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
// Create a new firewalled purse and resolve with its assigned id.
|
|
15
|
+
createPurse(name) {
|
|
16
|
+
return resultToPromise(unwrapVersionedResult(version, hostApi.coinPaymentCreatePurse(enumValue(version, { name })))).then(({ purse }) => purse);
|
|
17
|
+
},
|
|
18
|
+
// Query product-visible metadata and balance for a purse.
|
|
19
|
+
queryPurse(purse) {
|
|
20
|
+
return resultToPromise(unwrapVersionedResult(version, hostApi.coinPaymentQueryPurse(enumValue(version, { purse })))).then(({ info }) => info);
|
|
21
|
+
},
|
|
22
|
+
// Create a fresh receivable public key for depositing into a purse.
|
|
23
|
+
createReceivable(into) {
|
|
24
|
+
return resultToPromise(unwrapVersionedResult(version, hostApi.coinPaymentCreateReceivable(enumValue(version, { into })))).then(({ receivable }) => receivable);
|
|
25
|
+
},
|
|
26
|
+
// Create a cheque paying from a local purse to a receivable.
|
|
27
|
+
createCheque(from, to, amount) {
|
|
28
|
+
return resultToPromise(unwrapVersionedResult(version, hostApi.coinPaymentCreateCheque(enumValue(version, { from, to, amount })))).then(({ cheque }) => cheque);
|
|
29
|
+
},
|
|
30
|
+
// Transfer balance between local purses, streaming clearing status.
|
|
31
|
+
rebalancePurse(from, to, amount, onStatus) {
|
|
32
|
+
return stream(hostApi.coinPaymentRebalancePurse(enumValue(version, { from, to, amount }), payload => {
|
|
33
|
+
if (payload.tag === version)
|
|
34
|
+
onStatus(payload.value);
|
|
35
|
+
}));
|
|
36
|
+
},
|
|
37
|
+
// Delete a purse after draining its balance into another local purse.
|
|
38
|
+
deletePurse(target, drainInto, onStatus) {
|
|
39
|
+
return stream(hostApi.coinPaymentDeletePurse(enumValue(version, { target, drainInto }), payload => {
|
|
40
|
+
if (payload.tag === version)
|
|
41
|
+
onStatus(payload.value);
|
|
42
|
+
}));
|
|
43
|
+
},
|
|
44
|
+
// Claim coins from a cheque into the receivable's purse.
|
|
45
|
+
deposit(cheque, onStatus) {
|
|
46
|
+
return stream(hostApi.coinPaymentDeposit(enumValue(version, { cheque }), payload => {
|
|
47
|
+
if (payload.tag === version)
|
|
48
|
+
onStatus(payload.value);
|
|
49
|
+
}));
|
|
50
|
+
},
|
|
51
|
+
// Attempt to return coins associated with a receivable.
|
|
52
|
+
refund(receivable, onStatus) {
|
|
53
|
+
return stream(hostApi.coinPaymentRefund(enumValue(version, { receivable }), payload => {
|
|
54
|
+
if (payload.tag === version)
|
|
55
|
+
onStatus(payload.value);
|
|
56
|
+
}));
|
|
57
|
+
},
|
|
58
|
+
// Listen for a cheque delivered through a standard transmission channel.
|
|
59
|
+
listenForPayment(receivable, onDelivery) {
|
|
60
|
+
return stream(hostApi.coinPaymentListenForPayment(enumValue(version, { receivable }), payload => {
|
|
61
|
+
if (payload.tag === version)
|
|
62
|
+
onDelivery(payload.value);
|
|
63
|
+
}));
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
export const hostCoinPayment = createCoinPayment();
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,9 @@ export { accounts, createAccountsProvider, ringVrfKeyHandle } from './accounts.j
|
|
|
13
13
|
export type { ThemeMode } from './theme.js';
|
|
14
14
|
export { createThemeProvider } from './theme.js';
|
|
15
15
|
export { createLocalStorage, hostLocalStorage } from './localStorage.js';
|
|
16
|
+
export { createWorker, hostWorker } from './worker.js';
|
|
17
|
+
export type { Cheque, ClearingStatus, PaymentDelivery, PurseInfo, Receivable } from './coinPayment.js';
|
|
18
|
+
export { createCoinPayment, hostCoinPayment } from './coinPayment.js';
|
|
16
19
|
export type { NotificationId, PushNotificationInput } from './notification.js';
|
|
17
20
|
export { createNotificationManager, notificationManager } from './notification.js';
|
|
18
21
|
export { createPreimageManager, preimageManager } from './preimage.js';
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,8 @@ export { createStatementStore } from './statementStore.js';
|
|
|
9
9
|
export { accounts, createAccountsProvider, ringVrfKeyHandle } from './accounts.js';
|
|
10
10
|
export { createThemeProvider } from './theme.js';
|
|
11
11
|
export { createLocalStorage, hostLocalStorage } from './localStorage.js';
|
|
12
|
+
export { createWorker, hostWorker } from './worker.js';
|
|
13
|
+
export { createCoinPayment, hostCoinPayment } from './coinPayment.js';
|
|
12
14
|
export { createNotificationManager, notificationManager } from './notification.js';
|
|
13
15
|
export { createPreimageManager, preimageManager } from './preimage.js';
|
|
14
16
|
export { createPaymentManager, paymentManager } from './payments.js';
|
package/dist/localStorage.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Subscription } from '@novasamatech/host-api';
|
|
1
2
|
export declare const createLocalStorage: (transport?: import("@novasamatech/host-api").Transport) => {
|
|
2
3
|
clear(key: string): Promise<undefined>;
|
|
3
4
|
readBytes(key: string): Promise<Uint8Array<ArrayBufferLike> | undefined>;
|
|
@@ -6,6 +7,9 @@ export declare const createLocalStorage: (transport?: import("@novasamatech/host
|
|
|
6
7
|
writeString(key: string, value: string): Promise<undefined>;
|
|
7
8
|
readJSON(key: string): Promise<any>;
|
|
8
9
|
writeJSON(key: string, value: unknown): Promise<undefined>;
|
|
10
|
+
subscribeBytes(key: string, callback: (value: Uint8Array | undefined) => void): Subscription<void>;
|
|
11
|
+
subscribeString(key: string, callback: (value: string | undefined) => void): Subscription<void>;
|
|
12
|
+
subscribeJSON(key: string, callback: (value: unknown) => void): Subscription<void>;
|
|
9
13
|
};
|
|
10
14
|
export declare const hostLocalStorage: {
|
|
11
15
|
clear(key: string): Promise<undefined>;
|
|
@@ -15,4 +19,7 @@ export declare const hostLocalStorage: {
|
|
|
15
19
|
writeString(key: string, value: string): Promise<undefined>;
|
|
16
20
|
readJSON(key: string): Promise<any>;
|
|
17
21
|
writeJSON(key: string, value: unknown): Promise<undefined>;
|
|
22
|
+
subscribeBytes(key: string, callback: (value: Uint8Array | undefined) => void): Subscription<void>;
|
|
23
|
+
subscribeString(key: string, callback: (value: string | undefined) => void): Subscription<void>;
|
|
24
|
+
subscribeJSON(key: string, callback: (value: unknown) => void): Subscription<void>;
|
|
18
25
|
};
|
package/dist/localStorage.js
CHANGED
|
@@ -15,6 +15,17 @@ export const createLocalStorage = (transport = sandboxTransport) => {
|
|
|
15
15
|
function clearKey(key) {
|
|
16
16
|
return resultToPromise(unwrapVersionedResult(supportedVersion, hostApi.localStorageClear(enumValue(supportedVersion, key))));
|
|
17
17
|
}
|
|
18
|
+
function subscribeBytes(key, callback) {
|
|
19
|
+
const subscriber = hostApi.localStorageSubscribe(enumValue(supportedVersion, { key }), item => {
|
|
20
|
+
if (item.tag === supportedVersion) {
|
|
21
|
+
callback(item.value.value);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return {
|
|
25
|
+
unsubscribe: subscriber.unsubscribe,
|
|
26
|
+
onInterrupt: cb => subscriber.onInterrupt(v => cb(v.value)),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
18
29
|
return {
|
|
19
30
|
async clear(key) {
|
|
20
31
|
return clearKey(key);
|
|
@@ -40,6 +51,17 @@ export const createLocalStorage = (transport = sandboxTransport) => {
|
|
|
40
51
|
async writeJSON(key, value) {
|
|
41
52
|
return writeBytes(key, textEncoder.encode(JSON.stringify(value)));
|
|
42
53
|
},
|
|
54
|
+
// Emits the current value immediately, then on every later write or clear
|
|
55
|
+
// of the key. `undefined` means the key was cleared or is absent.
|
|
56
|
+
subscribeBytes(key, callback) {
|
|
57
|
+
return subscribeBytes(key, callback);
|
|
58
|
+
},
|
|
59
|
+
subscribeString(key, callback) {
|
|
60
|
+
return subscribeBytes(key, bytes => callback(bytes === undefined ? undefined : textDecoder.decode(bytes)));
|
|
61
|
+
},
|
|
62
|
+
subscribeJSON(key, callback) {
|
|
63
|
+
return subscribeBytes(key, bytes => callback(bytes === undefined || bytes.length === 0 ? undefined : JSON.parse(textDecoder.decode(bytes))));
|
|
64
|
+
},
|
|
43
65
|
};
|
|
44
66
|
};
|
|
45
67
|
export const hostLocalStorage = createLocalStorage();
|
package/dist/papiProvider.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createHostApi, enumValue, unwrapResultOrThrow } from '@novasamatech/host-api';
|
|
1
|
+
import { createHostApi, enumValue, isCallErrorFailure, unwrapResultOrThrow } from '@novasamatech/host-api';
|
|
2
2
|
import { getSyncProvider } from '@polkadot-api/json-rpc-provider-proxy';
|
|
3
3
|
import { sandboxTransport } from './sandboxTransport.js';
|
|
4
4
|
export function createPapiProvider(genesisHash,
|
|
@@ -311,6 +311,8 @@ __fallback, internal) {
|
|
|
311
311
|
.then(payload => {
|
|
312
312
|
switch (payload.tag) {
|
|
313
313
|
case 'v1': {
|
|
314
|
+
if (isCallErrorFailure(payload.value))
|
|
315
|
+
return false;
|
|
314
316
|
return unwrapResultOrThrow(payload.value, e => new Error(e.payload.reason));
|
|
315
317
|
}
|
|
316
318
|
default:
|
package/dist/worker.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Transport } from '@novasamatech/host-api';
|
|
2
|
+
export declare const createWorker: (transport?: Transport) => {
|
|
3
|
+
beginOperation(label?: string): Promise<number>;
|
|
4
|
+
endOperation(id: number): Promise<void>;
|
|
5
|
+
};
|
|
6
|
+
export declare const hostWorker: {
|
|
7
|
+
beginOperation(label?: string): Promise<number>;
|
|
8
|
+
endOperation(id: number): Promise<void>;
|
|
9
|
+
};
|
package/dist/worker.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createHostApi, enumValue } from '@novasamatech/host-api';
|
|
2
|
+
import { resultToPromise, unwrapVersionedResult } from './helpers.js';
|
|
3
|
+
import { sandboxTransport } from './sandboxTransport.js';
|
|
4
|
+
export const createWorker = (transport = sandboxTransport) => {
|
|
5
|
+
const supportedVersion = 'v1';
|
|
6
|
+
const hostApi = createHostApi(transport);
|
|
7
|
+
return {
|
|
8
|
+
// Begin a pending operation. The host keeps this worker alive while it has
|
|
9
|
+
// at least one open operation, so a background task runs to completion even
|
|
10
|
+
// after the product's surface goes away. Returns the operation id.
|
|
11
|
+
async beginOperation(label) {
|
|
12
|
+
const { id } = await resultToPromise(unwrapVersionedResult(supportedVersion, hostApi.workerBeginOperation(enumValue(supportedVersion, { label }))));
|
|
13
|
+
return id;
|
|
14
|
+
},
|
|
15
|
+
// End a pending operation. Idempotent: an unknown or already-ended id
|
|
16
|
+
// still resolves.
|
|
17
|
+
async endOperation(id) {
|
|
18
|
+
return resultToPromise(unwrapVersionedResult(supportedVersion, hostApi.workerEndOperation(enumValue(supportedVersion, { id }))));
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export const hostWorker = createWorker();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@novasamatech/host-api-wrapper",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.10.0",
|
|
5
5
|
"description": "Host API wrapper: integrate and run your product inside Polkadot browser.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"repository": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@polkadot/extension-inject": "^0.63.1",
|
|
29
29
|
"@polkadot-api/json-rpc-provider-proxy": "^0.4.0",
|
|
30
30
|
"@polkadot-api/substrate-bindings": "^0.20.3",
|
|
31
|
-
"@novasamatech/host-api": "0.
|
|
31
|
+
"@novasamatech/host-api": "0.10.0",
|
|
32
32
|
"polkadot-api": ">=2",
|
|
33
33
|
"neverthrow": "^8.2.0"
|
|
34
34
|
},
|