@novasamatech/product-sdk 0.5.2 → 0.5.4-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.
@@ -12,7 +12,7 @@ export async function createExtensionEnableFactory(transport) {
12
12
  const accountId = AccountId();
13
13
  async function enable() {
14
14
  async function getAccounts() {
15
- const response = await hostApi.get_non_product_accounts(enumValue('v1', undefined));
15
+ const response = await hostApi.getNonProductAccounts(enumValue('v1', undefined));
16
16
  return response.match(response => {
17
17
  assertEnumVariant(response, 'v1', UNSUPPORTED_VERSION_ERROR);
18
18
  return response.value.map(account => ({
@@ -51,7 +51,7 @@ export async function createExtensionEnableFactory(transport) {
51
51
  value: raw.data,
52
52
  },
53
53
  };
54
- const response = await hostApi.sign_raw(enumValue('v1', payload));
54
+ const response = await hostApi.signRaw(enumValue('v1', payload));
55
55
  return response.match(response => {
56
56
  assertEnumVariant(response, 'v1', UNSUPPORTED_VERSION_ERROR);
57
57
  return {
@@ -73,7 +73,7 @@ export async function createExtensionEnableFactory(transport) {
73
73
  withSignedTransaction: payload.withSignedTransaction,
74
74
  metadataHash: payload.metadataHash,
75
75
  };
76
- const response = await hostApi.sign_payload(enumValue('v1', codecPayload));
76
+ const response = await hostApi.signPayload(enumValue('v1', codecPayload));
77
77
  return response.match(response => {
78
78
  assertEnumVariant(response, 'v1', UNSUPPORTED_VERSION_ERROR);
79
79
  return {
@@ -87,7 +87,7 @@ export async function createExtensionEnableFactory(transport) {
87
87
  });
88
88
  },
89
89
  async createTransaction(payload) {
90
- const response = await hostApi.create_transaction_with_non_product_account(enumValue('v1', payload));
90
+ const response = await hostApi.createTransactionWithNonProductAccount(enumValue('v1', payload));
91
91
  return response.match(response => {
92
92
  assertEnumVariant(response, 'v1', UNSUPPORTED_VERSION_ERROR);
93
93
  return toHex(response.value);
@@ -0,0 +1,24 @@
1
+ import type { CodecType, HexString, Transport, VersionedPublicTxPayload } from '@novasamatech/host-api';
2
+ import type { InjectedAccounts } from '@polkadot/extension-inject/types';
3
+ import type { SignerPayloadJSON, SignerPayloadRaw, SignerResult } from '@polkadot/types/types/extrinsic';
4
+ interface Signer {
5
+ /**
6
+ * @description signs an extrinsic payload from a serialized form
7
+ */
8
+ signPayload?: (payload: SignerPayloadJSON) => Promise<SignerResult>;
9
+ /**
10
+ * @description signs a raw payload, only the bytes data as supplied
11
+ */
12
+ signRaw?: (raw: SignerPayloadRaw) => Promise<SignerResult>;
13
+ /**
14
+ * @description signs a transaction according to https://github.com/polkadot-js/api/issues/6213
15
+ */
16
+ createTransaction?: (payload: CodecType<typeof VersionedPublicTxPayload>) => Promise<HexString>;
17
+ }
18
+ interface Injected {
19
+ accounts: InjectedAccounts;
20
+ signer: Signer;
21
+ }
22
+ export declare function createNonProductExtensionEnableFactory(transport: Transport): Promise<(() => Promise<Injected>) | null>;
23
+ export declare function injectSpektrExtension(transport?: Transport | null): Promise<boolean>;
24
+ export {};
@@ -0,0 +1,121 @@
1
+ import { assertEnumVariant, createHostApi, enumValue, fromHex, toHex } from '@novasamatech/host-api';
2
+ import { injectExtension } from '@polkadot/extension-inject';
3
+ import { AccountId } from '@polkadot-api/substrate-bindings';
4
+ import { SpektrExtensionName, Version } from './constants.js';
5
+ import { sandboxTransport } from './sandboxTransport.js';
6
+ const UNSUPPORTED_VERSION_ERROR = 'Unsupported message version';
7
+ export async function createNonProductExtensionEnableFactory(transport) {
8
+ const ready = await transport.isReady();
9
+ if (!ready)
10
+ return null;
11
+ const hostApi = createHostApi(transport);
12
+ const accountId = AccountId();
13
+ async function enable() {
14
+ async function getAccounts() {
15
+ const response = await hostApi.getNonProductAccounts(enumValue('v1', undefined));
16
+ return response.match(response => {
17
+ assertEnumVariant(response, 'v1', UNSUPPORTED_VERSION_ERROR);
18
+ return response.value.map(account => ({
19
+ name: account.name,
20
+ address: accountId.dec(account.publicKey),
21
+ type: 'sr25519',
22
+ }));
23
+ }, err => {
24
+ assertEnumVariant(err, 'v1', UNSUPPORTED_VERSION_ERROR);
25
+ throw err.value;
26
+ });
27
+ }
28
+ return {
29
+ accounts: {
30
+ async get() {
31
+ return getAccounts();
32
+ },
33
+ subscribe(callback) {
34
+ getAccounts().then(callback);
35
+ return () => {
36
+ // empty
37
+ };
38
+ },
39
+ },
40
+ signer: {
41
+ async signRaw(raw) {
42
+ const payload = {
43
+ address: raw.address,
44
+ data: raw.type === 'bytes'
45
+ ? {
46
+ tag: 'Bytes',
47
+ value: fromHex(raw.data),
48
+ }
49
+ : {
50
+ tag: 'Payload',
51
+ value: raw.data,
52
+ },
53
+ };
54
+ const response = await hostApi.signRaw(enumValue('v1', payload));
55
+ return response.match(response => {
56
+ assertEnumVariant(response, 'v1', UNSUPPORTED_VERSION_ERROR);
57
+ return {
58
+ id: 0,
59
+ signature: response.value.signature,
60
+ signedTransaction: response.value.signedTransaction,
61
+ };
62
+ }, err => {
63
+ assertEnumVariant(err, 'v1', UNSUPPORTED_VERSION_ERROR);
64
+ throw err.value;
65
+ });
66
+ },
67
+ async signPayload(payload) {
68
+ const codecPayload = {
69
+ ...payload,
70
+ method: payload.method,
71
+ assetId: payload.assetId,
72
+ mode: payload.mode,
73
+ withSignedTransaction: payload.withSignedTransaction,
74
+ metadataHash: payload.metadataHash,
75
+ };
76
+ const response = await hostApi.signPayload(enumValue('v1', codecPayload));
77
+ return response.match(response => {
78
+ assertEnumVariant(response, 'v1', UNSUPPORTED_VERSION_ERROR);
79
+ return {
80
+ id: 0,
81
+ signature: response.value.signature,
82
+ signedTransaction: response.value.signedTransaction,
83
+ };
84
+ }, err => {
85
+ assertEnumVariant(err, 'v1', UNSUPPORTED_VERSION_ERROR);
86
+ throw err.value;
87
+ });
88
+ },
89
+ async createTransaction(payload) {
90
+ const response = await hostApi.createTransactionWithNonProductAccount(enumValue('v1', payload));
91
+ return response.match(response => {
92
+ assertEnumVariant(response, 'v1', UNSUPPORTED_VERSION_ERROR);
93
+ return toHex(response.value);
94
+ }, err => {
95
+ assertEnumVariant(err, 'v1', UNSUPPORTED_VERSION_ERROR);
96
+ throw err.value;
97
+ });
98
+ },
99
+ },
100
+ };
101
+ }
102
+ return enable;
103
+ }
104
+ export async function injectSpektrExtension(transport = sandboxTransport) {
105
+ if (!transport)
106
+ return false;
107
+ try {
108
+ const enable = await createNonProductExtensionEnableFactory(transport);
109
+ if (enable) {
110
+ injectExtension(enable, { name: SpektrExtensionName, version: Version });
111
+ return true;
112
+ }
113
+ else {
114
+ return false;
115
+ }
116
+ }
117
+ catch (e) {
118
+ transport.provider.logger.error('Error injecting extension', e);
119
+ return false;
120
+ }
121
+ }
@@ -0,0 +1,7 @@
1
+ import type { ConnectionStatus, Transport } from '@novasamatech/host-api';
2
+ export declare function createMetaProvider(transport?: Transport): {
3
+ subscribeConnectionStatus(callback: (connectionStatus: ConnectionStatus) => void): VoidFunction;
4
+ };
5
+ export declare const metaProvider: {
6
+ subscribeConnectionStatus(callback: (connectionStatus: ConnectionStatus) => void): VoidFunction;
7
+ };
@@ -0,0 +1,24 @@
1
+ import { sandboxTransport } from './sandboxTransport.js';
2
+ export function createMetaProvider(transport = sandboxTransport) {
3
+ // if (transport.isCorrectEnvironment() && typeof window !== 'undefined') {
4
+ // const getUrl = () => {
5
+ // return window.location.pathname + window.location.hash + window.location.search;
6
+ // };
7
+ //
8
+ // window.addEventListener('hashchange', () => {
9
+ // transport.postMessage('_', { tag: 'locationChangedV1', value: getUrl() });
10
+ // });
11
+ //
12
+ // window.addEventListener('popstate', () => {
13
+ // transport.postMessage('_', { tag: 'locationChangedV1', value: getUrl() });
14
+ // });
15
+ //
16
+ // transport.postMessage('_', { tag: 'locationChangedV1', value: getUrl() });
17
+ // }
18
+ return {
19
+ subscribeConnectionStatus(callback) {
20
+ return transport.onConnectionStatusChange(callback);
21
+ },
22
+ };
23
+ }
24
+ export const metaProvider = createMetaProvider();
@@ -0,0 +1,7 @@
1
+ import type { HexString, Transport } from '@novasamatech/host-api';
2
+ import type { JsonRpcProvider } from '@polkadot-api/json-rpc-provider';
3
+ type InternalParams = {
4
+ transport?: Transport;
5
+ };
6
+ export declare function createPapiProvider(genesisHash: HexString, __fallback?: JsonRpcProvider, internal?: InternalParams): JsonRpcProvider;
7
+ export {};
@@ -0,0 +1,60 @@
1
+ import { createHostApi, enumValue, unwrapResultOrThrow } from '@novasamatech/host-api';
2
+ import { getSyncProvider } from '@polkadot-api/json-rpc-provider-proxy';
3
+ import { sandboxTransport } from './sandboxTransport.js';
4
+ export function createPapiProvider(genesisHash,
5
+ // for testing purposes only, should not be used in real production code
6
+ __fallback, internal) {
7
+ const version = 'v1';
8
+ const transport = internal?.transport ?? sandboxTransport;
9
+ if (!transport.isCorrectEnvironment()) {
10
+ throw new Error('PapiProvider can only be used in a product environment');
11
+ }
12
+ const hostApi = createHostApi(transport);
13
+ const spektrProvider = onMessage => {
14
+ const subscription = hostApi.jsonrpcMessageSubscribe(enumValue(version, genesisHash), payload => {
15
+ switch (payload.tag) {
16
+ case version:
17
+ onMessage(payload.value);
18
+ break;
19
+ default:
20
+ transport.provider.logger.error('Unknown message version', payload.tag);
21
+ }
22
+ });
23
+ return {
24
+ send(message) {
25
+ hostApi.jsonrpcMessageSend(enumValue(version, [genesisHash, message]));
26
+ },
27
+ disconnect() {
28
+ subscription.unsubscribe();
29
+ },
30
+ };
31
+ };
32
+ function checkIfReady() {
33
+ return transport.isReady().then(ready => {
34
+ if (!ready)
35
+ return false;
36
+ return transport
37
+ .request('feature', enumValue('v1', enumValue('Chain', genesisHash)))
38
+ .then(payload => {
39
+ switch (payload.tag) {
40
+ case 'v1': {
41
+ return unwrapResultOrThrow(payload.value, e => new Error(e.payload.reason));
42
+ }
43
+ default:
44
+ throw new Error(`Unknown message version ${payload.tag}`);
45
+ }
46
+ })
47
+ .catch(e => {
48
+ transport.provider.logger.error('Error checking chain support', e);
49
+ return false;
50
+ });
51
+ });
52
+ }
53
+ return getSyncProvider(() => checkIfReady().then(ready => {
54
+ if (ready)
55
+ return spektrProvider;
56
+ if (__fallback)
57
+ return __fallback;
58
+ throw new Error(`Chain ${genesisHash} not supported by host`);
59
+ }));
60
+ }
@@ -0,0 +1,8 @@
1
+ import type { Provider } from '@novasamatech/host-api';
2
+ declare global {
3
+ interface Window {
4
+ __HOST_API_PORT__?: MessagePort;
5
+ }
6
+ }
7
+ export declare const sandboxProvider: Provider;
8
+ export declare const sandboxTransport: import("@novasamatech/host-api").Transport;
@@ -0,0 +1,85 @@
1
+ import { createDefaultLogger, createTransport } from '@novasamatech/host-api';
2
+ function getParentWindow() {
3
+ if (window.top) {
4
+ return window.top;
5
+ }
6
+ throw new Error('No parent window found');
7
+ }
8
+ function isIframe() {
9
+ try {
10
+ return window !== window.top;
11
+ }
12
+ catch {
13
+ return false;
14
+ }
15
+ }
16
+ function isWebview() {
17
+ try {
18
+ return window['__HOST_API_PORT__'] !== undefined;
19
+ }
20
+ catch {
21
+ return false;
22
+ }
23
+ }
24
+ function getWebviewPort() {
25
+ if (window['__HOST_API_PORT__']) {
26
+ return window['__HOST_API_PORT__'];
27
+ }
28
+ throw new Error('No webview port found');
29
+ }
30
+ function isValidMessage(event, sourceEnv, currentEnv) {
31
+ return (event.source !== currentEnv &&
32
+ event.source === sourceEnv &&
33
+ event.data &&
34
+ event.data.constructor.name === 'Uint8Array');
35
+ }
36
+ function createDefaultSdkProvider() {
37
+ const subscribers = new Set();
38
+ const handleMessage = (event) => {
39
+ const source = isIframe() ? getParentWindow() : isWebview() ? getWebviewPort() : null;
40
+ if (!source)
41
+ throw new Error('No message source found');
42
+ if (!isValidMessage(event, source, window))
43
+ return;
44
+ for (const subscriber of subscribers) {
45
+ subscriber(event.data);
46
+ }
47
+ };
48
+ if (isIframe()) {
49
+ window.addEventListener('message', handleMessage);
50
+ }
51
+ else if (isWebview()) {
52
+ getWebviewPort().addEventListener('message', handleMessage);
53
+ }
54
+ return {
55
+ logger: createDefaultLogger(),
56
+ isCorrectEnvironment() {
57
+ return isIframe() || isWebview();
58
+ },
59
+ postMessage(message) {
60
+ if (isIframe()) {
61
+ getParentWindow().postMessage(message, '*', [message.buffer]);
62
+ }
63
+ else if (isWebview()) {
64
+ getWebviewPort().postMessage(message, [message.buffer]);
65
+ }
66
+ },
67
+ subscribe(callback) {
68
+ subscribers.add(callback);
69
+ return () => {
70
+ subscribers.delete(callback);
71
+ };
72
+ },
73
+ dispose() {
74
+ subscribers.clear();
75
+ if (isIframe()) {
76
+ window.removeEventListener('message', handleMessage);
77
+ }
78
+ if (isWebview()) {
79
+ getWebviewPort().removeEventListener('message', handleMessage);
80
+ }
81
+ },
82
+ };
83
+ }
84
+ export const sandboxProvider = createDefaultSdkProvider();
85
+ export const sandboxTransport = createTransport(sandboxProvider);
@@ -0,0 +1,36 @@
1
+ import type { CodecType, ProductAccountId as ProductAccountIdCodec, SignedStatement as SignedStatementCodec, Statement as StatementCodec, Topic as TopicCodec, Transport } from '@novasamatech/host-api';
2
+ export type Statement = CodecType<typeof StatementCodec>;
3
+ export type SignedStatement = CodecType<typeof SignedStatementCodec>;
4
+ export type Topic = CodecType<typeof TopicCodec>;
5
+ export type ProductAccountId = CodecType<typeof ProductAccountIdCodec>;
6
+ export declare const createStatementStore: (transport?: Transport) => {
7
+ query(topics: Topic[]): Promise<SignedStatement[]>;
8
+ subscribe(topics: Topic[], callback: (statements: SignedStatement[]) => void): import("@novasamatech/host-api").Subscription;
9
+ createProof(accountId: ProductAccountId, statement: Statement): Promise<{
10
+ tag: "Sr25519";
11
+ value: {
12
+ signature: Uint8Array<ArrayBufferLike>;
13
+ signer: Uint8Array<ArrayBufferLike>;
14
+ };
15
+ } | {
16
+ tag: "Ed25519";
17
+ value: {
18
+ signature: Uint8Array<ArrayBufferLike>;
19
+ signer: Uint8Array<ArrayBufferLike>;
20
+ };
21
+ } | {
22
+ tag: "Ecdsa";
23
+ value: {
24
+ signature: Uint8Array<ArrayBufferLike>;
25
+ signer: Uint8Array<ArrayBufferLike>;
26
+ };
27
+ } | {
28
+ tag: "OnChain";
29
+ value: {
30
+ who: Uint8Array<ArrayBufferLike>;
31
+ blockHash: Uint8Array<ArrayBufferLike>;
32
+ event: bigint;
33
+ };
34
+ }>;
35
+ submit(signedStatement: SignedStatement): Promise<void>;
36
+ };
@@ -0,0 +1,47 @@
1
+ import { createHostApi, enumValue } from '@novasamatech/host-api';
2
+ import { sandboxTransport } from './sandboxTransport.js';
3
+ export const createStatementStore = (transport = sandboxTransport) => {
4
+ const hostApi = createHostApi(transport);
5
+ return {
6
+ async query(topics) {
7
+ const result = await hostApi.statementStoreQuery(enumValue('v1', topics));
8
+ return result.match(payload => {
9
+ if (payload.tag === 'v1') {
10
+ return payload.value;
11
+ }
12
+ throw new Error(`Unknown response version ${payload.tag}`);
13
+ }, err => {
14
+ throw err.value;
15
+ });
16
+ },
17
+ subscribe(topics, callback) {
18
+ return hostApi.statementStoreSubscribe(enumValue('v1', topics), payload => {
19
+ if (payload.tag === 'v1') {
20
+ callback(payload.value);
21
+ }
22
+ });
23
+ },
24
+ async createProof(accountId, statement) {
25
+ const result = await hostApi.statementStoreCreateProof(enumValue('v1', [accountId, statement]));
26
+ return result.match(payload => {
27
+ if (payload.tag === 'v1') {
28
+ return payload.value;
29
+ }
30
+ throw new Error(`Unknown response version ${payload.tag}`);
31
+ }, err => {
32
+ throw err.value;
33
+ });
34
+ },
35
+ async submit(signedStatement) {
36
+ const result = await hostApi.statementStoreSubmit(enumValue('v1', signedStatement));
37
+ return result.match(payload => {
38
+ if (payload.tag === 'v1') {
39
+ return;
40
+ }
41
+ throw new Error(`Unknown response version ${payload.tag}`);
42
+ }, err => {
43
+ throw err.value;
44
+ });
45
+ },
46
+ };
47
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@novasamatech/product-sdk",
3
3
  "type": "module",
4
- "version": "0.5.2",
4
+ "version": "0.5.4-0",
5
5
  "description": "Polkadot product SDK: integrate and run your product inside Polkadot browser.",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -27,10 +27,10 @@
27
27
  ],
28
28
  "dependencies": {
29
29
  "@polkadot/extension-inject": "^0.62.6",
30
- "@polkadot-api/substrate-bindings": "^0.16.6",
30
+ "@polkadot-api/substrate-bindings": "^0.16.5",
31
31
  "@polkadot-api/json-rpc-provider": "^0.0.4",
32
32
  "@polkadot-api/json-rpc-provider-proxy": "^0.2.7",
33
- "@novasamatech/host-api": "0.5.2"
33
+ "@novasamatech/host-api": "0.5.4-0"
34
34
  },
35
35
  "publishConfig": {
36
36
  "access": "public"