@cartridge/controller 0.5.7 → 0.5.8

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/src/provider.ts CHANGED
@@ -1,10 +1,13 @@
1
1
  import { WalletAccount } from "starknet";
2
2
  import {
3
3
  AddInvokeTransactionParameters,
4
+ AddStarknetChainParameters,
4
5
  Errors,
5
6
  Permission,
7
+ RequestAccountsParameters,
6
8
  RequestFn,
7
9
  StarknetWindowObject,
10
+ SwitchStarknetChainParameters,
8
11
  TypedData,
9
12
  WalletEventHandlers,
10
13
  WalletEventListener,
@@ -13,7 +16,6 @@ import {
13
16
  import manifest from "../package.json";
14
17
 
15
18
  import { icon } from "./icon";
16
- import { ProviderOptions } from "./types";
17
19
 
18
20
  export default abstract class BaseProvider implements StarknetWindowObject {
19
21
  public id = "controller";
@@ -21,16 +23,9 @@ export default abstract class BaseProvider implements StarknetWindowObject {
21
23
  public version = manifest.version;
22
24
  public icon = icon;
23
25
 
24
- public rpc: URL;
25
26
  public account?: WalletAccount;
26
27
  public subscriptions: WalletEvents[] = [];
27
28
 
28
- constructor(options: ProviderOptions) {
29
- const { rpc } = options;
30
-
31
- this.rpc = new URL(rpc);
32
- }
33
-
34
29
  request: RequestFn = async (call) => {
35
30
  switch (call.type) {
36
31
  case "wallet_getPermissions":
@@ -47,8 +42,11 @@ export default abstract class BaseProvider implements StarknetWindowObject {
47
42
  return [this.account.address];
48
43
  }
49
44
 
45
+ const silentMode =
46
+ call.params && (call.params as RequestAccountsParameters).silent_mode;
47
+
50
48
  this.account = await this.probe();
51
- if (!this.account) {
49
+ if (!this.account && !silentMode) {
52
50
  this.account = await this.connect();
53
51
  }
54
52
 
@@ -66,26 +64,22 @@ export default abstract class BaseProvider implements StarknetWindowObject {
66
64
  data: "wallet_watchAsset not implemented",
67
65
  } as Errors.UNEXPECTED_ERROR;
68
66
 
69
- case "wallet_addStarknetChain":
70
- throw {
71
- code: 63,
72
- message: "An unexpected error occurred",
73
- data: "wallet_addStarknetChain not implemented",
74
- } as Errors.UNEXPECTED_ERROR;
67
+ case "wallet_addStarknetChain": {
68
+ let params = call.params as AddStarknetChainParameters;
69
+ return this.addStarknetChain(params);
70
+ }
75
71
 
76
- case "wallet_switchStarknetChain":
77
- throw {
78
- code: 63,
79
- message: "An unexpected error occurred",
80
- data: "wallet_switchStarknetChain not implemented",
81
- } as Errors.UNEXPECTED_ERROR;
72
+ case "wallet_switchStarknetChain": {
73
+ let params = call.params as SwitchStarknetChainParameters;
74
+ return this.switchStarknetChain(params.chainId);
75
+ }
82
76
 
83
77
  case "wallet_requestChainId":
84
78
  if (!this.account) {
85
79
  throw {
86
80
  code: 63,
87
81
  message: "An unexpected error occurred",
88
- data: "wallet_deploymentData not implemented",
82
+ data: "Account not initialized",
89
83
  } as Errors.UNEXPECTED_ERROR;
90
84
  }
91
85
 
@@ -103,7 +97,7 @@ export default abstract class BaseProvider implements StarknetWindowObject {
103
97
  throw {
104
98
  code: 63,
105
99
  message: "An unexpected error occurred",
106
- data: "wallet_deploymentData not implemented",
100
+ data: "Account not initialized",
107
101
  } as Errors.UNEXPECTED_ERROR;
108
102
  }
109
103
 
@@ -173,6 +167,26 @@ export default abstract class BaseProvider implements StarknetWindowObject {
173
167
  }
174
168
  };
175
169
 
170
+ protected emitNetworkChanged(chainId: string) {
171
+ this.subscriptions
172
+ .filter((sub) => sub.type === "networkChanged")
173
+ .forEach((sub) => {
174
+ (sub.handler as WalletEventHandlers["networkChanged"])(chainId);
175
+ });
176
+ }
177
+
178
+ protected emitAccountsChanged(accounts: string[]) {
179
+ this.subscriptions
180
+ .filter((sub) => sub.type === "accountsChanged")
181
+ .forEach((sub) => {
182
+ (sub.handler as WalletEventHandlers["accountsChanged"])(accounts);
183
+ });
184
+ }
185
+
176
186
  abstract probe(): Promise<WalletAccount | undefined>;
177
187
  abstract connect(): Promise<WalletAccount | undefined>;
188
+ abstract switchStarknetChain(chainId: string): Promise<boolean>;
189
+ abstract addStarknetChain(
190
+ chain: AddStarknetChainParameters,
191
+ ): Promise<boolean>;
178
192
  }
@@ -5,6 +5,7 @@ import { KEYCHAIN_URL } from "../constants";
5
5
  import BaseProvider from "../provider";
6
6
  import { toWasmPolicies } from "../utils";
7
7
  import { SessionPolicies } from "@cartridge/presets";
8
+ import { AddStarknetChainParameters } from "@starknet-io/types-js";
8
9
 
9
10
  interface SessionRegistration {
10
11
  username: string;
@@ -26,14 +27,15 @@ export default class SessionProvider extends BaseProvider {
26
27
  public name = "Controller Session";
27
28
 
28
29
  protected _chainId: string;
29
-
30
+ protected _rpcUrl: string;
30
31
  protected _username?: string;
31
32
  protected _redirectUrl: string;
32
33
  protected _policies: SessionPolicies;
33
34
 
34
35
  constructor({ rpc, chainId, policies, redirectUrl }: SessionOptions) {
35
- super({ rpc });
36
+ super();
36
37
 
38
+ this._rpcUrl = rpc;
37
39
  this._chainId = chainId;
38
40
  this._redirectUrl = redirectUrl;
39
41
  this._policies = policies;
@@ -76,7 +78,7 @@ export default class SessionProvider extends BaseProvider {
76
78
  this._redirectUrl
77
79
  }&redirect_query_name=startapp&policies=${JSON.stringify(
78
80
  this._policies,
79
- )}&rpc_url=${this.rpc}`;
81
+ )}&rpc_url=${this._rpcUrl}`;
80
82
 
81
83
  localStorage.setItem("lastUsedConnector", this.id);
82
84
  window.open(url, "_blank");
@@ -84,6 +86,14 @@ export default class SessionProvider extends BaseProvider {
84
86
  return;
85
87
  }
86
88
 
89
+ switchStarknetChain(_chainId: string): Promise<boolean> {
90
+ throw new Error("switchStarknetChain not implemented");
91
+ }
92
+
93
+ addStarknetChain(_chain: AddStarknetChainParameters): Promise<boolean> {
94
+ throw new Error("addStarknetChain not implemented");
95
+ }
96
+
87
97
  disconnect(): Promise<void> {
88
98
  localStorage.removeItem("sessionSigner");
89
99
  localStorage.removeItem("session");
@@ -127,7 +137,7 @@ export default class SessionProvider extends BaseProvider {
127
137
 
128
138
  this._username = sessionRegistration.username;
129
139
  this.account = new SessionAccount(this, {
130
- rpcUrl: this.rpc.toString(),
140
+ rpcUrl: this._rpcUrl,
131
141
  privateKey: signer.privKey,
132
142
  address: sessionRegistration.address,
133
143
  ownerGuid: sessionRegistration.ownerGuid,
@@ -11,6 +11,7 @@ import SessionAccount from "../session/account";
11
11
  import BaseProvider from "../provider";
12
12
  import { toWasmPolicies } from "../utils";
13
13
  import { SessionPolicies } from "@cartridge/presets";
14
+ import { AddStarknetChainParameters } from "@starknet-io/types-js";
14
15
 
15
16
  interface SessionRegistration {
16
17
  username: string;
@@ -25,6 +26,7 @@ export default class TelegramProvider extends BaseProvider {
25
26
  protected _chainId: string;
26
27
  protected _username?: string;
27
28
  protected _policies: SessionPolicies;
29
+ private _rpcUrl: string;
28
30
 
29
31
  constructor({
30
32
  rpc,
@@ -37,10 +39,9 @@ export default class TelegramProvider extends BaseProvider {
37
39
  policies: SessionPolicies;
38
40
  tmaUrl: string;
39
41
  }) {
40
- super({
41
- rpc,
42
- });
42
+ super();
43
43
 
44
+ this._rpcUrl = rpc;
44
45
  this._tmaUrl = tmaUrl;
45
46
  this._chainId = chainId;
46
47
  this._policies = policies;
@@ -77,7 +78,7 @@ export default class TelegramProvider extends BaseProvider {
77
78
  this._tmaUrl
78
79
  }&redirect_query_name=startapp&policies=${JSON.stringify(
79
80
  this._policies,
80
- )}&rpc_url=${this.rpc}`;
81
+ )}&rpc_url=${this._rpcUrl}`;
81
82
 
82
83
  localStorage.setItem("lastUsedConnector", this.id);
83
84
  openLink(url);
@@ -86,6 +87,14 @@ export default class TelegramProvider extends BaseProvider {
86
87
  return;
87
88
  }
88
89
 
90
+ switchStarknetChain(_chainId: string): Promise<boolean> {
91
+ throw new Error("switchStarknetChain not implemented");
92
+ }
93
+
94
+ addStarknetChain(_chain: AddStarknetChainParameters): Promise<boolean> {
95
+ throw new Error("addStarknetChain not implemented");
96
+ }
97
+
89
98
  disconnect(): Promise<void> {
90
99
  cloudStorage.deleteItem("sessionSigner");
91
100
  cloudStorage.deleteItem("session");
@@ -118,7 +127,7 @@ export default class TelegramProvider extends BaseProvider {
118
127
 
119
128
  this._username = sessionRegistration.username;
120
129
  this.account = new SessionAccount(this, {
121
- rpcUrl: this.rpc.toString(),
130
+ rpcUrl: this._rpcUrl,
122
131
  privateKey: signer.privKey,
123
132
  address: sessionRegistration.address,
124
133
  ownerGuid: sessionRegistration.ownerGuid,
package/src/types.ts CHANGED
@@ -7,16 +7,12 @@ import {
7
7
  } from "starknet";
8
8
  import {
9
9
  AddInvokeTransactionResult,
10
+ ChainId,
10
11
  Signature,
11
12
  TypedData,
12
13
  } from "@starknet-io/types-js";
13
14
  import { KeychainIFrame, ProfileIFrame } from "./iframe";
14
- import {
15
- ColorMode,
16
- Policies,
17
- Policy,
18
- SessionPolicies,
19
- } from "@cartridge/presets";
15
+ import { ColorMode, Policy, SessionPolicies } from "@cartridge/presets";
20
16
 
21
17
  export type Session = {
22
18
  chainId: constants.StarknetChainId;
@@ -100,7 +96,7 @@ export type ControllerAccounts = Record<ContractAddress, CartridgeID>;
100
96
  export interface Keychain {
101
97
  probe(rpcUrl: string): Promise<ProbeReply | ConnectError>;
102
98
  connect(
103
- policies: Policies,
99
+ policies: SessionPolicies,
104
100
  rpcUrl: string,
105
101
  ): Promise<ConnectReply | ConnectError>;
106
102
  disconnect(): void;
@@ -134,6 +130,7 @@ export interface Keychain {
134
130
  openPurchaseCredits(): void;
135
131
  openExecute(calls: Call[]): Promise<void>;
136
132
  }
133
+
137
134
  export interface Profile {
138
135
  navigate(path: string): void;
139
136
  }
@@ -161,13 +158,17 @@ export type IFrameOptions = {
161
158
  colorMode?: ColorMode;
162
159
  };
163
160
 
161
+ export type Chain = {
162
+ rpcUrl: string;
163
+ };
164
+
164
165
  export type ProviderOptions = {
165
- /** The URL of the RPC */
166
- rpc: string;
166
+ defaultChainId: ChainId;
167
+ chains: Chain[];
167
168
  };
168
169
 
169
170
  export type KeychainOptions = IFrameOptions & {
170
- policies?: Policies;
171
+ policies?: SessionPolicies;
171
172
  /** The URL of keychain */
172
173
  url?: string;
173
174
  /** The origin of keychain */
@@ -193,8 +194,6 @@ export type ProfileContextTypeVariant =
193
194
  | "achievements"
194
195
  | "activity";
195
196
 
196
- export type Prefund = { address: string; min: string };
197
-
198
197
  export type Tokens = {
199
198
  erc20?: string[];
200
199
  };