@novasamatech/product-sdk 0.6.17 → 0.7.0-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 +46 -0
- package/dist/accounts.js +49 -44
- package/dist/index.d.ts +5 -0
- package/dist/index.js +3 -0
- package/dist/injectWeb3.js +22 -10
- package/dist/payments.d.ts +36 -0
- package/dist/payments.js +45 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -289,6 +289,21 @@ const config = await storage.readJSON('config');
|
|
|
289
289
|
await storage.clear('key');
|
|
290
290
|
```
|
|
291
291
|
|
|
292
|
+
### Derive Entropy
|
|
293
|
+
|
|
294
|
+
The Derive Entropy function allows products to derive deterministic 32-byte entropy scoped to the product and a caller-chosen key.
|
|
295
|
+
|
|
296
|
+
```ts
|
|
297
|
+
import { deriveEntropy } from '@novasamatech/product-sdk';
|
|
298
|
+
|
|
299
|
+
const result = await deriveEntropy(new Uint8Array([1, 2, 3]));
|
|
300
|
+
|
|
301
|
+
if (result.isOk()) {
|
|
302
|
+
const entropy: Uint8Array = result.value;
|
|
303
|
+
console.log('Derived entropy:', entropy);
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
292
307
|
### Preimage Manager
|
|
293
308
|
|
|
294
309
|
The Preimage Manager allows you to lookup and submit preimages to the host application.
|
|
@@ -318,3 +333,34 @@ subscription.unsubscribe();
|
|
|
318
333
|
const preimageKey = await manager.submit(new Uint8Array([1, 2, 3, 4]));
|
|
319
334
|
```
|
|
320
335
|
|
|
336
|
+
### Payment manager
|
|
337
|
+
|
|
338
|
+
```ts
|
|
339
|
+
import { createPaymentManager } from '@novasamatech/product-sdk';
|
|
340
|
+
|
|
341
|
+
const payments = createPaymentManager();
|
|
342
|
+
|
|
343
|
+
// Subscribe to the user's payment balance (host will prompt for consent)
|
|
344
|
+
const balanceSub = payments.subscribeBalance(balance => {
|
|
345
|
+
console.log('Available:', balance.available);
|
|
346
|
+
console.log('Pending:', balance.pending);
|
|
347
|
+
});
|
|
348
|
+
balanceSub.onInterrupt(() => console.log('Balance access denied or lost'));
|
|
349
|
+
|
|
350
|
+
// Top up the user's balance from a product account
|
|
351
|
+
await payments.topUp(1_000_000n, {
|
|
352
|
+
type: 'productAccount',
|
|
353
|
+
dotNsIdentifier: 'my-product.dot',
|
|
354
|
+
derivationIndex: 0,
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
// Request a payment from the user (host shows confirmation UI)
|
|
358
|
+
const destination = new Uint8Array(32); // 32-byte AccountId
|
|
359
|
+
const receipt = await payments.requestPayment(500_000n, destination);
|
|
360
|
+
|
|
361
|
+
// Track payment settlement
|
|
362
|
+
const statusSub = payments.subscribePaymentStatus(receipt.id, status => {
|
|
363
|
+
if (status.type === 'completed') console.log('Payment settled');
|
|
364
|
+
if (status.type === 'failed') console.log('Payment failed:', status.reason);
|
|
365
|
+
});
|
|
366
|
+
```
|
package/dist/accounts.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CreateProofErr, RequestCredentialsErr, RingLocation, assertEnumVariant, createHostApi, enumValue, fromHex, isEnumVariant, toHex, } from '@novasamatech/host-api';
|
|
1
|
+
import { CreateProofErr, RequestCredentialsErr, RingLocation, SigningPayload, SigningPayloadWithoutAccount, SigningRawPayload, SigningRawPayloadWithoutAccount, assertEnumVariant, createHostApi, enumValue, fromHex, isEnumVariant, toHex, } from '@novasamatech/host-api';
|
|
2
2
|
import { getPolkadotSignerFromPjs } from '@polkadot-api/pjs-signer';
|
|
3
3
|
import { err, ok } from 'neverthrow';
|
|
4
4
|
import { sandboxTransport } from './sandboxTransport.js';
|
|
@@ -57,20 +57,24 @@ export const createAccountsProvider = (transport = sandboxTransport) => {
|
|
|
57
57
|
getProductAccountSigner(account) {
|
|
58
58
|
return getPolkadotSignerFromPjs(toHex(account.publicKey), async (payload) => {
|
|
59
59
|
const codecPayload = {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
60
|
+
account: [account.dotNsIdentifier, account.derivationIndex],
|
|
61
|
+
payload: {
|
|
62
|
+
blockHash: asHex(payload.blockHash),
|
|
63
|
+
blockNumber: asHex(payload.blockNumber),
|
|
64
|
+
era: asHex(payload.era),
|
|
65
|
+
genesisHash: asHex(payload.genesisHash),
|
|
66
|
+
nonce: asHex(payload.nonce),
|
|
67
|
+
method: asHex(payload.method),
|
|
68
|
+
specVersion: asHex(payload.specVersion),
|
|
69
|
+
transactionVersion: asHex(payload.transactionVersion),
|
|
70
|
+
metadataHash: payload.metadataHash ? asHex(payload.metadataHash) : undefined,
|
|
71
|
+
tip: asHex(payload.tip),
|
|
72
|
+
assetId: payload.assetId !== undefined ? payload.assetId : undefined,
|
|
73
|
+
mode: payload.mode,
|
|
74
|
+
withSignedTransaction: payload.withSignedTransaction,
|
|
75
|
+
signedExtensions: payload.signedExtensions,
|
|
76
|
+
version: payload.version,
|
|
77
|
+
},
|
|
74
78
|
};
|
|
75
79
|
const response = await hostApi.signPayload(enumValue('v1', codecPayload));
|
|
76
80
|
return response.match(response => {
|
|
@@ -86,11 +90,11 @@ export const createAccountsProvider = (transport = sandboxTransport) => {
|
|
|
86
90
|
});
|
|
87
91
|
}, async (raw) => {
|
|
88
92
|
const payload = {
|
|
89
|
-
|
|
90
|
-
|
|
93
|
+
account: [account.dotNsIdentifier, account.derivationIndex],
|
|
94
|
+
payload: raw.type === 'bytes'
|
|
91
95
|
? {
|
|
92
96
|
tag: 'Bytes',
|
|
93
|
-
value: fromHex(raw.data),
|
|
97
|
+
value: fromHex(asHex(raw.data)),
|
|
94
98
|
}
|
|
95
99
|
: {
|
|
96
100
|
tag: 'Payload',
|
|
@@ -121,22 +125,26 @@ export const createAccountsProvider = (transport = sandboxTransport) => {
|
|
|
121
125
|
getNonProductAccountSigner(account) {
|
|
122
126
|
return getPolkadotSignerFromPjs(toHex(account.publicKey), async (payload) => {
|
|
123
127
|
const codecPayload = {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
128
|
+
signer: payload.address,
|
|
129
|
+
payload: {
|
|
130
|
+
blockHash: asHex(payload.blockHash),
|
|
131
|
+
blockNumber: asHex(payload.blockNumber),
|
|
132
|
+
era: asHex(payload.era),
|
|
133
|
+
genesisHash: asHex(payload.genesisHash),
|
|
134
|
+
nonce: asHex(payload.nonce),
|
|
135
|
+
method: asHex(payload.method),
|
|
136
|
+
specVersion: asHex(payload.specVersion),
|
|
137
|
+
transactionVersion: asHex(payload.transactionVersion),
|
|
138
|
+
metadataHash: payload.metadataHash ? asHex(payload.metadataHash) : undefined,
|
|
139
|
+
tip: asHex(payload.tip),
|
|
140
|
+
assetId: payload.assetId !== undefined ? payload.assetId : undefined,
|
|
141
|
+
mode: payload.mode,
|
|
142
|
+
withSignedTransaction: payload.withSignedTransaction,
|
|
143
|
+
signedExtensions: payload.signedExtensions,
|
|
144
|
+
version: payload.version,
|
|
145
|
+
},
|
|
138
146
|
};
|
|
139
|
-
const response = await hostApi.
|
|
147
|
+
const response = await hostApi.signPayloadWithNonProductAccount(enumValue('v1', codecPayload));
|
|
140
148
|
return response.match(response => {
|
|
141
149
|
assertEnumVariant(response, 'v1', UNSUPPORTED_VERSION_ERROR);
|
|
142
150
|
return {
|
|
@@ -150,18 +158,10 @@ export const createAccountsProvider = (transport = sandboxTransport) => {
|
|
|
150
158
|
});
|
|
151
159
|
}, async (raw) => {
|
|
152
160
|
const payload = {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
? {
|
|
156
|
-
tag: 'Bytes',
|
|
157
|
-
value: fromHex(raw.data),
|
|
158
|
-
}
|
|
159
|
-
: {
|
|
160
|
-
tag: 'Payload',
|
|
161
|
-
value: raw.data,
|
|
162
|
-
},
|
|
161
|
+
signer: raw.address,
|
|
162
|
+
payload: { tag: 'Bytes', value: fromHex(asHex(raw.data)) },
|
|
163
163
|
};
|
|
164
|
-
const response = await hostApi.
|
|
164
|
+
const response = await hostApi.signRawWithNonProductAccount(enumValue('v1', payload));
|
|
165
165
|
return response.match(response => {
|
|
166
166
|
assertEnumVariant(response, 'v1', UNSUPPORTED_VERSION_ERROR);
|
|
167
167
|
return {
|
|
@@ -177,3 +177,8 @@ export const createAccountsProvider = (transport = sandboxTransport) => {
|
|
|
177
177
|
},
|
|
178
178
|
};
|
|
179
179
|
};
|
|
180
|
+
function asHex(v) {
|
|
181
|
+
if (v.startsWith('0x'))
|
|
182
|
+
return v;
|
|
183
|
+
return `0x${v}`;
|
|
184
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,5 +10,10 @@ export type { ProductAccountId, SignedStatement, Statement, Topic } from './stat
|
|
|
10
10
|
export { createStatementStore } from './statementStore.js';
|
|
11
11
|
export type { AccountConnectionStatus, ProductAccount } from './accounts.js';
|
|
12
12
|
export { createAccountsProvider } from './accounts.js';
|
|
13
|
+
export type { ThemeMode, ThemeSubscription } from './theme.js';
|
|
14
|
+
export { createThemeProvider } from './theme.js';
|
|
13
15
|
export { createLocalStorage, hostLocalStorage } from './localStorage.js';
|
|
14
16
|
export { createPreimageManager, preimageManager } from './preimage.js';
|
|
17
|
+
export type { PaymentBalance, PaymentStatus, TopUpSource } from './payments.js';
|
|
18
|
+
export { createPaymentManager, paymentManager } from './payments.js';
|
|
19
|
+
export { deriveEntropy } from './deriveEntropy.js';
|
package/dist/index.js
CHANGED
|
@@ -7,5 +7,8 @@ export { createPapiProvider } from './papiProvider.js';
|
|
|
7
7
|
export { createProductChatManager, matchChatCustomRenderers } from './chat.js';
|
|
8
8
|
export { createStatementStore } from './statementStore.js';
|
|
9
9
|
export { createAccountsProvider } from './accounts.js';
|
|
10
|
+
export { createThemeProvider } from './theme.js';
|
|
10
11
|
export { createLocalStorage, hostLocalStorage } from './localStorage.js';
|
|
11
12
|
export { createPreimageManager, preimageManager } from './preimage.js';
|
|
13
|
+
export { createPaymentManager, paymentManager } from './payments.js';
|
|
14
|
+
export { deriveEntropy } from './deriveEntropy.js';
|
package/dist/injectWeb3.js
CHANGED
|
@@ -40,8 +40,8 @@ export async function createNonProductExtensionEnableFactory(transport) {
|
|
|
40
40
|
signer: {
|
|
41
41
|
async signRaw(raw) {
|
|
42
42
|
const payload = {
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
signer: raw.address,
|
|
44
|
+
payload: raw.type === 'bytes'
|
|
45
45
|
? {
|
|
46
46
|
tag: 'Bytes',
|
|
47
47
|
value: fromHex(raw.data),
|
|
@@ -51,7 +51,7 @@ export async function createNonProductExtensionEnableFactory(transport) {
|
|
|
51
51
|
value: raw.data,
|
|
52
52
|
},
|
|
53
53
|
};
|
|
54
|
-
const response = await hostApi.
|
|
54
|
+
const response = await hostApi.signRawWithNonProductAccount(enumValue('v1', payload));
|
|
55
55
|
return response.match(response => {
|
|
56
56
|
assertEnumVariant(response, 'v1', UNSUPPORTED_VERSION_ERROR);
|
|
57
57
|
return {
|
|
@@ -66,14 +66,26 @@ export async function createNonProductExtensionEnableFactory(transport) {
|
|
|
66
66
|
},
|
|
67
67
|
async signPayload(payload) {
|
|
68
68
|
const codecPayload = {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
signer: payload.address,
|
|
70
|
+
payload: {
|
|
71
|
+
blockHash: payload.blockHash,
|
|
72
|
+
blockNumber: payload.blockNumber,
|
|
73
|
+
era: payload.era,
|
|
74
|
+
genesisHash: payload.genesisHash,
|
|
75
|
+
nonce: payload.nonce,
|
|
76
|
+
method: payload.method,
|
|
77
|
+
specVersion: payload.specVersion,
|
|
78
|
+
transactionVersion: payload.transactionVersion,
|
|
79
|
+
metadataHash: payload.metadataHash,
|
|
80
|
+
tip: payload.tip,
|
|
81
|
+
assetId: payload.assetId,
|
|
82
|
+
mode: payload.mode,
|
|
83
|
+
withSignedTransaction: payload.withSignedTransaction,
|
|
84
|
+
signedExtensions: payload.signedExtensions,
|
|
85
|
+
version: payload.version,
|
|
86
|
+
},
|
|
75
87
|
};
|
|
76
|
-
const response = await hostApi.
|
|
88
|
+
const response = await hostApi.signPayloadWithNonProductAccount(enumValue('v1', codecPayload));
|
|
77
89
|
return response.match(response => {
|
|
78
90
|
assertEnumVariant(response, 'v1', UNSUPPORTED_VERSION_ERROR);
|
|
79
91
|
return {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Subscription, Transport } from '@novasamatech/host-api';
|
|
2
|
+
export type PaymentBalance = {
|
|
3
|
+
available: bigint;
|
|
4
|
+
};
|
|
5
|
+
export type PaymentStatus = {
|
|
6
|
+
type: 'processing';
|
|
7
|
+
} | {
|
|
8
|
+
type: 'completed';
|
|
9
|
+
} | {
|
|
10
|
+
type: 'failed';
|
|
11
|
+
reason: string;
|
|
12
|
+
};
|
|
13
|
+
export type TopUpSource = {
|
|
14
|
+
type: 'productAccount';
|
|
15
|
+
dotNsIdentifier: string;
|
|
16
|
+
derivationIndex: number;
|
|
17
|
+
} | {
|
|
18
|
+
type: 'privateKey';
|
|
19
|
+
key: Uint8Array;
|
|
20
|
+
};
|
|
21
|
+
export declare const createPaymentManager: (transport?: Transport) => {
|
|
22
|
+
subscribeBalance(callback: (balance: PaymentBalance) => void): Subscription;
|
|
23
|
+
topUp(amount: bigint, source: TopUpSource): Promise<void>;
|
|
24
|
+
requestPayment(amount: bigint, destination: Uint8Array): Promise<{
|
|
25
|
+
id: string;
|
|
26
|
+
}>;
|
|
27
|
+
subscribePaymentStatus(id: string, callback: (status: PaymentStatus) => void): Subscription;
|
|
28
|
+
};
|
|
29
|
+
export declare const paymentManager: {
|
|
30
|
+
subscribeBalance(callback: (balance: PaymentBalance) => void): Subscription;
|
|
31
|
+
topUp(amount: bigint, source: TopUpSource): Promise<void>;
|
|
32
|
+
requestPayment(amount: bigint, destination: Uint8Array): Promise<{
|
|
33
|
+
id: string;
|
|
34
|
+
}>;
|
|
35
|
+
subscribePaymentStatus(id: string, callback: (status: PaymentStatus) => void): Subscription;
|
|
36
|
+
};
|
package/dist/payments.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { createHostApi, enumValue } from '@novasamatech/host-api';
|
|
2
|
+
import { resultToPromise, unwrapVersionedResult } from './helpers.js';
|
|
3
|
+
import { sandboxTransport } from './sandboxTransport.js';
|
|
4
|
+
export const createPaymentManager = (transport = sandboxTransport) => {
|
|
5
|
+
const hostApi = createHostApi(transport);
|
|
6
|
+
const version = 'v1';
|
|
7
|
+
return {
|
|
8
|
+
subscribeBalance(callback) {
|
|
9
|
+
return hostApi.paymentBalanceSubscribe(enumValue(version, undefined), payload => {
|
|
10
|
+
if (payload.tag === version) {
|
|
11
|
+
callback(payload.value);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
},
|
|
15
|
+
topUp(amount, source) {
|
|
16
|
+
const sourceCodec = source.type === 'productAccount'
|
|
17
|
+
? {
|
|
18
|
+
tag: 'ProductAccount',
|
|
19
|
+
value: [source.dotNsIdentifier, source.derivationIndex],
|
|
20
|
+
}
|
|
21
|
+
: { tag: 'PrivateKey', value: source.key };
|
|
22
|
+
return resultToPromise(unwrapVersionedResult(version, hostApi.paymentTopUp(enumValue(version, { amount, source: sourceCodec }))));
|
|
23
|
+
},
|
|
24
|
+
requestPayment(amount, destination) {
|
|
25
|
+
return resultToPromise(unwrapVersionedResult(version, hostApi.paymentRequest(enumValue(version, { amount, destination }))));
|
|
26
|
+
},
|
|
27
|
+
subscribePaymentStatus(id, callback) {
|
|
28
|
+
return hostApi.paymentStatusSubscribe(enumValue(version, id), payload => {
|
|
29
|
+
if (payload.tag === version) {
|
|
30
|
+
const raw = payload.value;
|
|
31
|
+
if (raw.tag === 'Processing') {
|
|
32
|
+
callback({ type: 'processing' });
|
|
33
|
+
}
|
|
34
|
+
else if (raw.tag === 'Completed') {
|
|
35
|
+
callback({ type: 'completed' });
|
|
36
|
+
}
|
|
37
|
+
else if (raw.tag === 'Failed') {
|
|
38
|
+
callback({ type: 'failed', reason: raw.value });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
export const paymentManager = createPaymentManager();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@novasamatech/product-sdk",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.0-0",
|
|
5
5
|
"description": "Polkadot product SDK: integrate and run your product inside Polkadot browser.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"repository": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@polkadot-api/substrate-bindings": "^0.17.0",
|
|
30
30
|
"@polkadot-api/json-rpc-provider": "^0.0.4",
|
|
31
31
|
"@polkadot-api/json-rpc-provider-proxy": "^0.2.7",
|
|
32
|
-
"@novasamatech/host-api": "0.
|
|
32
|
+
"@novasamatech/host-api": "0.7.0-0"
|
|
33
33
|
},
|
|
34
34
|
"publishConfig": {
|
|
35
35
|
"access": "public"
|