@effectstream/wallets 0.100.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.
@@ -0,0 +1,196 @@
1
+ import { AddressType, type MidnightAddress } from "@effectstream/utils";
2
+ import type {
3
+ ConnectedAPI,
4
+ InitialAPI,
5
+ Signature,
6
+ } from "@midnight-ntwrk/dapp-connector-api";
7
+ import semver from "semver";
8
+ import {
9
+ type IInjectedConnector,
10
+ type ActiveConnection,
11
+ type IProvider,
12
+ type AddressAndType,
13
+ type UserSignature,
14
+ type IConnector,
15
+ type ConnectionOption,
16
+ optionToActive,
17
+ } from "../IProvider.ts";
18
+ import { getWindow } from "../windows.ts";
19
+
20
+ export type MidnightApi = ConnectedAPI;
21
+
22
+ const COMPATIBLE_CONNECTOR_API_VERSION = ">=1.0.0";
23
+ const DEFAULT_NETWORK_ID = "undeployed";
24
+
25
+ // TODO Implement this class
26
+ export class MidnightConnector
27
+ implements IConnector<MidnightApi>, IInjectedConnector<MidnightApi> {
28
+ private provider: MidnightProvider | undefined;
29
+ private static INSTANCE: undefined | MidnightConnector = undefined;
30
+ private static networkId = DEFAULT_NETWORK_ID;
31
+
32
+ static getWalletOptions(): ConnectionOption<MidnightApi>[] {
33
+ const midnightApi: Record<string, InitialAPI> = (getWindow() as any)
34
+ ?.midnight ?? {};
35
+ console.log("MidnightConnector.getWalletOptions: window.midnight content:", midnightApi);
36
+ const options = Object.entries(midnightApi).reduce((options, [key, api]) => {
37
+ console.log(`MidnightConnector.getWalletOptions: Checking wallet "${key}"`, api);
38
+ if (!isInitialApi(api)) {
39
+ console.log(`MidnightConnector.getWalletOptions: Wallet "${key}" is NOT a valid InitialAPI (missing connect or apiVersion)`);
40
+ return options;
41
+ }
42
+ if (!isCompatibleApiVersion(api.apiVersion)) {
43
+ console.log(`MidnightConnector.getWalletOptions: Wallet "${key}" has incompatible version ${api.apiVersion} (required: ${COMPATIBLE_CONNECTOR_API_VERSION})`);
44
+ return options;
45
+ }
46
+ const name = api.rdns?.trim() || key;
47
+ const displayName = api.name?.trim() || name;
48
+ console.log(`MidnightConnector.getWalletOptions: Wallet "${key}" is COMPATIBLE. Name: ${name}, DisplayName: ${displayName}`);
49
+ options.push({
50
+ metadata: {
51
+ name,
52
+ displayName,
53
+ icon: api.icon,
54
+ },
55
+ api: () => connectWithNetwork(api, MidnightConnector.networkId),
56
+ });
57
+ return options;
58
+ }, [] as ConnectionOption<MidnightApi>[]);
59
+ console.log(`MidnightConnector.getWalletOptions: Found ${options.length} compatible wallets`);
60
+ return options;
61
+ }
62
+
63
+ static instance(): MidnightConnector {
64
+ if (MidnightConnector.INSTANCE == null) {
65
+ const newInstance = new MidnightConnector();
66
+ MidnightConnector.INSTANCE = newInstance;
67
+ }
68
+ return MidnightConnector.INSTANCE;
69
+ }
70
+
71
+ setNetworkId = (networkId: string): void => {
72
+ MidnightConnector.networkId = networkId || DEFAULT_NETWORK_ID;
73
+ };
74
+
75
+ getOrThrowProvider = (): MidnightProvider => {
76
+ if (this.provider == null) {
77
+ throw new Error(`MidnightConnector provider isn't initialized yet`);
78
+ }
79
+ return this.provider;
80
+ };
81
+
82
+ getProvider = (): undefined | MidnightProvider => {
83
+ return this.provider;
84
+ };
85
+
86
+ isConnected(): boolean {
87
+ return this.provider != null;
88
+ }
89
+
90
+ connectSimple = async (): Promise<MidnightProvider> => {
91
+ if (this.provider != null) {
92
+ return this.provider;
93
+ }
94
+ const options = MidnightConnector.getWalletOptions();
95
+ if (options.length === 0) {
96
+ throw new Error(`No Midnight wallet found`);
97
+ }
98
+
99
+ return await this.connectExternal(await optionToActive(options[0]));
100
+ };
101
+
102
+ connectNamed = async (name: string): Promise<MidnightProvider> => {
103
+ if (this.provider?.getConnection().metadata?.name === name) {
104
+ return this.provider;
105
+ }
106
+ const provider = MidnightConnector.getWalletOptions().find(
107
+ entry => entry.metadata.name === name
108
+ );
109
+ if (provider == null) {
110
+ throw new Error(`Midnight wallet ${name} not found`);
111
+ }
112
+ return await this.connectExternal(await optionToActive(provider));
113
+ }
114
+
115
+ connectExternal = async (conn: ActiveConnection<MidnightApi>): Promise<MidnightProvider> => {
116
+ if (this.provider?.getConnection().metadata?.name === conn.metadata.name) {
117
+ return this.provider;
118
+ }
119
+ this.provider = await MidnightProvider.init(conn);
120
+ return this.provider;
121
+ }
122
+
123
+ }
124
+
125
+ // TODO Implement this class
126
+ export class MidnightProvider implements IProvider<MidnightApi> {
127
+ constructor(
128
+ private readonly conn: ActiveConnection<MidnightApi>,
129
+ readonly address: MidnightAddress
130
+ ) {}
131
+
132
+ static init = async (
133
+ conn: ActiveConnection<MidnightApi>
134
+ ): Promise<MidnightProvider> => {
135
+ const hexAddress = await MidnightProvider.fetchAddress(conn);
136
+ // const prefix = pickBech32Prefix(hexAddress);
137
+ // const words = bech32.toWords(hexStringToUint8Array(hexAddress));
138
+ // const userAddress = bech32.encode(prefix, words, 200);
139
+
140
+ return new MidnightProvider(conn, hexAddress as MidnightAddress);
141
+ };
142
+
143
+ getConnection(): ActiveConnection<MidnightApi> {
144
+ return this.conn;
145
+ }
146
+
147
+ signMessage = async (
148
+ message: string,
149
+ keyType: "unshielded" = "unshielded"
150
+ ): Promise<UserSignature> => {
151
+ const signature = (await this.conn.api.signData(message, {
152
+ encoding: "text",
153
+ keyType,
154
+ })) as Signature;
155
+ return signature.signature;
156
+ };
157
+
158
+ getAddress(): AddressAndType {
159
+ return {
160
+ type: AddressType.MIDNIGHT,
161
+ address: this.address,
162
+ }
163
+ }
164
+
165
+ static fetchAddress = async (conn: ActiveConnection<MidnightApi>): Promise<string> => {
166
+ const addresses = await conn.api.getShieldedAddresses();
167
+ if (!addresses?.shieldedAddress) {
168
+ throw new Error("Midnight wallet did not return a shielded address");
169
+ }
170
+ return addresses.shieldedAddress;
171
+ };
172
+ }
173
+
174
+ const isInitialApi = (api: InitialAPI | undefined): api is InitialAPI => {
175
+ return (
176
+ !!api &&
177
+ typeof api.connect === "function" &&
178
+ typeof api.apiVersion === "string"
179
+ );
180
+ };
181
+
182
+ const isCompatibleApiVersion = (apiVersion: string): boolean => {
183
+ return semver.satisfies(
184
+ apiVersion,
185
+ COMPATIBLE_CONNECTOR_API_VERSION,
186
+ { includePrerelease: true }
187
+ );
188
+ };
189
+
190
+ const connectWithNetwork = async (
191
+ api: InitialAPI,
192
+ networkId: string
193
+ ): Promise<ConnectedAPI> => {
194
+ const connect = api.connect.bind(api);
195
+ return await connect(networkId);
196
+ };
@@ -0,0 +1,36 @@
1
+ import type { Result } from "@effectstream/utils";
2
+ import type { IProvider } from "../IProvider.ts";
3
+ import type { WalletMode, ApiForMode } from "../utils.ts";
4
+ import { type LoginInfoMap, connectInjected } from "../wallet-modes.ts";
5
+ import { MidnightConnector } from "./midnight.ts";
6
+
7
+ export async function checkMidnightWalletStatus(): Promise<Result<string>> {
8
+ const provider = MidnightConnector.instance().getProvider();
9
+ if (provider == null) {
10
+ return {
11
+ success: false,
12
+ errorMessage: "No Midnight wallet found",
13
+ };
14
+ }
15
+
16
+ return { success: true, result: "OK" };
17
+ }
18
+
19
+ export async function midnightLoginWrapper(
20
+ loginInfo: LoginInfoMap[WalletMode.Midnight]
21
+ ): Promise<Result<IProvider<ApiForMode<WalletMode.Midnight>>>> {
22
+ const connector = MidnightConnector.instance();
23
+ connector.setNetworkId(loginInfo.networkId ?? "undeployed");
24
+ const loginResult = await connectInjected(
25
+ "midnightLoginWrapper",
26
+ loginInfo,
27
+ connector
28
+ );
29
+ if (loginResult.success === false) {
30
+ return loginResult;
31
+ }
32
+ return {
33
+ success: true,
34
+ result: loginResult.result,
35
+ };
36
+ }
@@ -0,0 +1,175 @@
1
+ import * as AuroMinaApi from "@aurowallet/mina-provider";
2
+ import { AddressType } from "@effectstream/utils";
3
+ import {
4
+ type IConnector,
5
+ type IInjectedConnector,
6
+ type ConnectionOption,
7
+ type IProvider,
8
+ optionToActive,
9
+ type ActiveConnection,
10
+ type AddressAndType,
11
+ type UserSignature,
12
+ } from "../IProvider.ts";
13
+ import { getWindow } from "../windows.ts";
14
+
15
+ export type MinaApi = AuroMinaApi.default;
16
+
17
+ type MinaAddress = any;
18
+
19
+ // JSR Error: modifying global types is not allowed
20
+ // declare global {
21
+ // interface Window {
22
+ // mina?: Record<string, { name?: string; enable?: () => Promise<MinaApi> }>;
23
+ // }
24
+ // }
25
+
26
+ export class MinaConnector
27
+ implements IConnector<MinaApi>, IInjectedConnector<MinaApi>
28
+ {
29
+ private provider: MinaProvider | undefined;
30
+ private static INSTANCE: undefined | MinaConnector = undefined;
31
+
32
+ static getWalletOptions(): ConnectionOption<MinaApi>[] {
33
+ const minaApi: Record<string, { name?: string; enable?: () => Promise<MinaApi> }> = (getWindow() as any)?.mina;
34
+ if (minaApi == null || !minaApi.isAuro) return [];
35
+
36
+ return [
37
+ {
38
+ metadata: {
39
+ name: "auro",
40
+ displayName: "Auro Wallet",
41
+ },
42
+ api: async (): Promise<MinaApi> => {
43
+ return minaApi as unknown as MinaApi;
44
+ },
45
+ },
46
+ ];
47
+ }
48
+
49
+ static instance(): MinaConnector {
50
+ if (MinaConnector.INSTANCE == null) {
51
+ const newInstance = new MinaConnector();
52
+ MinaConnector.INSTANCE = newInstance;
53
+ }
54
+ return MinaConnector.INSTANCE;
55
+ }
56
+
57
+ async connectSimple(): Promise<IProvider<any>> {
58
+ if (this.provider != null) {
59
+ return this.provider;
60
+ }
61
+
62
+ const options = MinaConnector.getWalletOptions();
63
+
64
+ if (options.length === 0) {
65
+ throw new Error(`No Mina wallet found`);
66
+ }
67
+
68
+ return await this.connectExternal(await optionToActive(options[0]));
69
+ }
70
+
71
+ async connectNamed(name: string): Promise<IProvider<any>> {
72
+ if (this.provider?.getConnection().metadata?.name === name) {
73
+ return this.provider;
74
+ }
75
+ const provider = MinaConnector.getWalletOptions().find(
76
+ (entry) => entry.metadata.name === name
77
+ );
78
+ if (provider == null) {
79
+ throw new Error(`MinaProvider: unsupported connection type ${name}`);
80
+ }
81
+ return await this.connectExternal(await optionToActive(provider));
82
+ }
83
+
84
+ connectExternal = async (
85
+ conn: ActiveConnection<MinaApi>
86
+ ): Promise<MinaProvider> => {
87
+ if (this.provider?.getConnection().metadata?.name === conn.metadata.name) {
88
+ return this.provider;
89
+ }
90
+
91
+ this.provider = await MinaProvider.init(conn);
92
+
93
+ conn.api.on("accountsChanged", (accounts) => {
94
+ if (!accounts || !accounts[0] || accounts[0] !== this.provider?.address) {
95
+ this.provider = undefined;
96
+ }
97
+ });
98
+
99
+ return this.provider;
100
+ };
101
+ getProvider = (): undefined | MinaProvider => {
102
+ return this.provider;
103
+ };
104
+ getOrThrowProvider = (): MinaProvider => {
105
+ if (this.provider == null) {
106
+ throw new Error(`MinaConnector provider isn't initialized yet`);
107
+ }
108
+ return this.provider;
109
+ };
110
+ isConnected = (): boolean => {
111
+ return this.provider != null;
112
+ };
113
+ }
114
+
115
+ export class MinaProvider implements IProvider<MinaApi> {
116
+ constructor(
117
+ private readonly conn: ActiveConnection<MinaApi>,
118
+ readonly address: MinaAddress
119
+ ) {}
120
+
121
+ static init = async (
122
+ conn: ActiveConnection<MinaApi>
123
+ ): Promise<MinaProvider> => {
124
+ const address = await MinaProvider.fetchAddress(conn);
125
+
126
+ return new MinaProvider(conn, address);
127
+ };
128
+ getConnection = (): ActiveConnection<MinaApi> => {
129
+ return this.conn;
130
+ };
131
+ getAddress = (): AddressAndType => {
132
+ return {
133
+ type: AddressType.MINA,
134
+ address: this.address,
135
+ };
136
+ };
137
+ signMessage = async (message: string): Promise<UserSignature> => {
138
+ // There is no way of choosing the signing account here. At most we could
139
+ // monitor the changed events and erroring out if it changed.
140
+ const signed = await this.conn.api.signMessage({ message: message });
141
+
142
+ if ("signature" in signed) {
143
+ const { signature } = signed;
144
+
145
+ const networkKind = await this.conn.api.requestNetwork();
146
+
147
+ // only these two options are used
148
+ // https://github.com/aurowallet/auro-wallet-browser-extension/blob/624de322dd99baaa09617bbad4a4a838f0a88edc/src/background/lib/index.js#L17
149
+ // this is part of the hashed message
150
+ const network =
151
+ networkKind.networkID === "mina:mainnet" ? "mainnet" : "testnet";
152
+
153
+ return `${signature.field};${signature.scalar};${network}`;
154
+ } else {
155
+ throw new Error("Failed to sign message");
156
+ }
157
+ };
158
+
159
+ static fetchAddress = async (
160
+ conn: ActiveConnection<MinaApi>
161
+ ): Promise<string> => {
162
+ try {
163
+ const addresses = await conn.api.requestAccounts();
164
+ if ("length" in addresses && addresses.length > 0) {
165
+ return addresses[0];
166
+ } else {
167
+ throw new Error("requestAccounts request failed");
168
+ }
169
+ } catch (err) {
170
+ console.log("[pickMinaAddress] error calling requestAccounts:", err);
171
+ }
172
+
173
+ throw new Error("[pickMinaAddress] no used or unused addresses");
174
+ };
175
+ }
@@ -0,0 +1,22 @@
1
+ import type { Result } from "@effectstream/utils";
2
+ import type { IProvider } from "../IProvider.ts";
3
+ import type { WalletMode, ApiForMode } from "../utils.ts";
4
+ import { type LoginInfoMap, connectInjected } from "../wallet-modes.ts";
5
+ import { MinaConnector } from "./mina.ts";
6
+
7
+ export async function minaLoginWrapper(
8
+ loginInfo: LoginInfoMap[WalletMode.Mina]
9
+ ): Promise<Result<IProvider<ApiForMode<WalletMode.Mina>>>> {
10
+ const loginResult = await connectInjected(
11
+ "minaLoginWrapper",
12
+ loginInfo,
13
+ MinaConnector.instance()
14
+ );
15
+ if (loginResult.success === false) {
16
+ return loginResult;
17
+ }
18
+ return {
19
+ success: true,
20
+ result: loginResult.result,
21
+ };
22
+ }
package/src/mod.ts ADDED
@@ -0,0 +1,10 @@
1
+ export type { IProvider, AddressAndType, UserSignature, WalletOption } from "./IProvider.ts";
2
+ export type { Wallet } from "./types.ts";
3
+ export type { AddressType, WalletAddress } from "@effectstream/utils";
4
+ export { accountPayload_, accountMessages } from "@effectstream/concise";
5
+ export { WalletMode, WalletNameMap } from "./utils.ts";
6
+ // Main entry point
7
+ export { walletLogin } from "./wallets.ts";
8
+ export { allInjectedWallets } from "./utils.ts";
9
+ export { getAddressType } from "./wallet-modes.ts";
10
+ export * from "./effectstream.ts";
@@ -0,0 +1,166 @@
1
+ import type {
2
+ InjectedExtension,
3
+ InjectedWindowProvider,
4
+ } from "@polkadot/extension-inject/types";
5
+ import { AddressType } from "@effectstream/utils";
6
+ import {
7
+ type IConnector,
8
+ type IInjectedConnector,
9
+ type ConnectionOption,
10
+ type ActiveConnection,
11
+ optionToActive,
12
+ type IProvider,
13
+ type AddressAndType,
14
+ type UserSignature,
15
+ } from "../IProvider.ts";
16
+ import { utf8ToHex } from "web3-utils";
17
+ import { getWindow } from "../windows.ts";
18
+
19
+ // @polkadot/extension-dapp is browser-only (its bundle touches `window` at module
20
+ // load). Import it lazily inside the methods that need it so this file can be
21
+ // parsed in Node/Bun test contexts — matches the non-browser design note in
22
+ // ../windows.ts.
23
+ export type PolkadotAddress = string;
24
+ export type PolkadotApi = InjectedExtension;
25
+
26
+ // declare global {
27
+ // interface Window {
28
+ // injectedWeb3?: Record<string, InjectedWindowProvider>;
29
+ // }
30
+ // }
31
+
32
+ export class PolkadotConnector
33
+ implements IConnector<PolkadotApi>, IInjectedConnector<PolkadotApi>
34
+ {
35
+ private provider: PolkadotProvider | undefined;
36
+ private static INSTANCE: undefined | PolkadotConnector = undefined;
37
+
38
+ static async getWalletOptions(): Promise<ConnectionOption<PolkadotApi>[]> {
39
+ const injectedWeb3: Record<string, InjectedWindowProvider> = (getWindow() as any)?.injectedWeb3;
40
+ if (injectedWeb3 == null) return [];
41
+ return Object.keys(injectedWeb3).map((wallet) => ({
42
+ metadata: {
43
+ name: wallet,
44
+ // polkadot provides no way to get a human-friendly name or icon for wallets
45
+ displayName: wallet,
46
+ },
47
+ api: async (): Promise<PolkadotApi> => {
48
+ const { web3Enable, web3FromSource } = await import("@polkadot/extension-dapp");
49
+ await web3Enable(/*gameName*/ "paima");
50
+ const injector = await web3FromSource(wallet);
51
+ return injector;
52
+ },
53
+ }));
54
+ }
55
+
56
+ static instance(): PolkadotConnector {
57
+ if (PolkadotConnector.INSTANCE == null) {
58
+ const newInstance = new PolkadotConnector();
59
+ PolkadotConnector.INSTANCE = newInstance;
60
+ }
61
+ return PolkadotConnector.INSTANCE;
62
+ }
63
+ connectSimple = async (): Promise<PolkadotProvider> => {
64
+ if (this.provider != null) {
65
+ return this.provider;
66
+ }
67
+
68
+ const { web3Enable, web3Accounts, web3FromAddress } = await import("@polkadot/extension-dapp");
69
+ const extensions = await web3Enable(/*gameName*/ "paima");
70
+ if (extensions.length === 0) {
71
+ throw new Error(`[polkadot] no extension detected`);
72
+ }
73
+
74
+ // we get all accounts instead of picking a specific extension
75
+ // because some extensions could have no accounts in them
76
+ const allAccounts = await web3Accounts();
77
+ for (const account of allAccounts) {
78
+ const injector = await web3FromAddress(account.address);
79
+ if (injector.signer.signRaw == null) continue;
80
+ return await this.connectExternal({
81
+ metadata: {
82
+ name: account.meta.source,
83
+ // polkadot provides no way to get a human-friendly name or icon for wallets
84
+ displayName: account.meta.source,
85
+ },
86
+ api: injector,
87
+ });
88
+ }
89
+ throw new Error("[polkadot] No account detected that supports signing! Found extensions: " + extensions.map(e => e.name).join(", "));
90
+ };
91
+ connectExternal = async (
92
+ conn: ActiveConnection<PolkadotApi>
93
+ ): Promise<PolkadotProvider> => {
94
+ if (this.provider?.getConnection().metadata?.name === conn.metadata.name) {
95
+ return this.provider;
96
+ }
97
+ this.provider = await PolkadotProvider.init(conn);
98
+ return this.provider;
99
+ };
100
+ connectNamed = async (name: string): Promise<PolkadotProvider> => {
101
+ if (this.provider?.getConnection().metadata?.name === name) {
102
+ return this.provider;
103
+ }
104
+ const provider = (await PolkadotConnector.getWalletOptions()).find(
105
+ (entry) => entry.metadata.name === name
106
+ );
107
+ if (provider == null) {
108
+ throw new Error(`Polkadot wallet ${name} not found`);
109
+ }
110
+ return await this.connectExternal(await optionToActive(provider));
111
+ };
112
+ getProvider = (): undefined | PolkadotProvider => {
113
+ return this.provider;
114
+ };
115
+ getOrThrowProvider = (): PolkadotProvider => {
116
+ if (this.provider == null) {
117
+ throw new Error(`PolkadotConnector not initialized yet`);
118
+ }
119
+ return this.provider;
120
+ };
121
+ isConnected = (): boolean => {
122
+ return this.provider != null;
123
+ };
124
+ }
125
+
126
+ export class PolkadotProvider implements IProvider<PolkadotApi> {
127
+ constructor(
128
+ private readonly conn: ActiveConnection<PolkadotApi>,
129
+ readonly address: PolkadotAddress
130
+ ) {}
131
+ static init = async (
132
+ conn: ActiveConnection<PolkadotApi>
133
+ ): Promise<PolkadotProvider> => {
134
+ // { address, name, type: "sr25519" }
135
+ const addresses = await conn.api.accounts.get(true);
136
+ const account = addresses.filter(a => a.type === "sr25519")[0]?.address;
137
+ if (account == null) {
138
+ throw new Error("Unknown error while receiving Polkadot accounts");
139
+ }
140
+
141
+ return new PolkadotProvider(conn, account);
142
+ };
143
+ getConnection = (): ActiveConnection<PolkadotApi> => {
144
+ return this.conn;
145
+ };
146
+ getAddress = (): AddressAndType => {
147
+ return {
148
+ type: AddressType.POLKADOT,
149
+ address: this.address,
150
+ };
151
+ };
152
+ signMessage = async (message: string): Promise<UserSignature> => {
153
+ if (this.conn.api.signer.signRaw == null) {
154
+ throw new Error(
155
+ `[polkadot] extension ${this.conn.metadata.name} does not support signRaw`
156
+ );
157
+ }
158
+ const hexMessage = utf8ToHex(message);
159
+ const { signature } = await this.conn.api.signer.signRaw({
160
+ address: this.getAddress().address,
161
+ data: hexMessage,
162
+ type: "bytes",
163
+ });
164
+ return signature;
165
+ };
166
+ }
@@ -0,0 +1,30 @@
1
+ // import { buildEndpointErrorFxn, PaimaMiddlewareErrorCode } from '../errors.js';
2
+ // import { getGameName } from '../state.js';
3
+ // import type { LoginInfoMap } from '../types.js';
4
+ // import { PolkadotConnector } from '@effectstream/providers';
5
+ // import type { ApiForMode, IProvider, WalletMode } from '@effectstream/providers';
6
+ // import { connectInjected } from './wallet-modes.js';
7
+ // import type { Result } from '@effectstream/utils';
8
+
9
+ import type { Result } from "@effectstream/utils";
10
+ import type { IProvider } from "../IProvider.ts";
11
+ import type { WalletMode, ApiForMode } from "../utils.ts";
12
+ import { type LoginInfoMap, connectInjected } from "../wallet-modes.ts";
13
+ import { PolkadotConnector } from "./polkadot.ts";
14
+
15
+ export async function polkadotLoginWrapper(
16
+ loginInfo: LoginInfoMap[WalletMode.Polkadot]
17
+ ): Promise<Result<IProvider<ApiForMode<WalletMode.Polkadot>>>> {
18
+ const loginResult = await connectInjected(
19
+ 'polkadotLoginWrapper',
20
+ loginInfo,
21
+ PolkadotConnector.instance()
22
+ );
23
+ if (loginResult.success === false) {
24
+ return loginResult;
25
+ }
26
+ return {
27
+ success: true,
28
+ result: loginResult.result,
29
+ };
30
+ }
package/src/types.ts ADDED
@@ -0,0 +1,61 @@
1
+ export type Hash = string;
2
+ import type { WalletAddress } from "@effectstream/utils";
3
+ import type { IProvider, UserSignature, WalletOption } from "./IProvider.ts";
4
+
5
+ export type SignFunction = (message: string) => Promise<UserSignature>;
6
+
7
+ export type QueryValue = string | number | boolean;
8
+ export type QueryOptions = Record<string, QueryValue>;
9
+
10
+ export interface Wallet {
11
+ provider: IProvider<unknown>;
12
+ walletAddress: WalletAddress;
13
+ metadata: WalletOption;
14
+ }
15
+
16
+ interface BatcherPostResponseSuccessful {
17
+ success: true;
18
+ hash: Hash;
19
+ }
20
+
21
+ interface BatcherPostResponseUnsuccessful {
22
+ success: false;
23
+ message: string;
24
+ code?: number;
25
+ }
26
+
27
+ export type BatcherPostResponse =
28
+ | BatcherPostResponseSuccessful
29
+ | BatcherPostResponseUnsuccessful;
30
+
31
+ interface BatcherTrackResponseCore {
32
+ success: true;
33
+ hash: Hash;
34
+ }
35
+
36
+ interface BatcherTrackResponsePosted extends BatcherTrackResponseCore {
37
+ status: "posted";
38
+ block_height: number;
39
+ transaction_hash: Hash;
40
+ }
41
+
42
+ interface BatcherTrackResponseRejected extends BatcherTrackResponseCore {
43
+ status: "rejected";
44
+ message: string;
45
+ }
46
+
47
+ interface BatcherTrackResponseOther extends BatcherTrackResponseCore {
48
+ status: "accepted" | "validating";
49
+ }
50
+
51
+ export type BatcherTrackResponse =
52
+ | BatcherTrackResponsePosted
53
+ | BatcherTrackResponseRejected
54
+ | BatcherTrackResponseOther;
55
+
56
+ export type BaseSuccessResponse = {
57
+ success: true;
58
+ };
59
+
60
+ export type PostDataResponse = BaseSuccessResponse & { blockHeight: number };
61
+ export type PostDataResponseAsync = BaseSuccessResponse & { hash: string };