@cartridge/controller 0.7.13-alpha.3 → 0.7.13
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/.turbo/turbo-build$colon$deps.log +15 -15
- package/.turbo/turbo-build.log +15 -15
- package/dist/index.js +238 -211
- package/dist/index.js.map +1 -1
- package/dist/node/index.cjs +1 -1
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +2 -4
- package/dist/node/index.d.ts +2 -4
- package/dist/node/index.js +1 -1
- package/dist/node/index.js.map +1 -1
- package/dist/{provider-M8-BWFF8.js → provider-C4iZV8Y5.js} +2 -2
- package/dist/provider-C4iZV8Y5.js.map +1 -0
- package/dist/session.js +2 -2
- package/dist/stats.html +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/wallets/argent/index.d.ts +3 -1
- package/dist/wallets/bridge.d.ts +2 -4
- package/dist/wallets/metamask/index.d.ts +3 -1
- package/dist/wallets/phantom/index.d.ts +3 -1
- package/dist/wallets/rabby/index.d.ts +2 -1
- package/dist/wallets/turnkey/index.d.ts +1 -0
- package/dist/wallets/types.d.ts +2 -1
- package/dist/wallets/wallet-connect/index.d.ts +2 -1
- package/package.json +4 -4
- package/src/types.ts +1 -0
- package/src/wallets/argent/index.ts +10 -5
- package/src/wallets/bridge.ts +22 -17
- package/src/wallets/metamask/index.ts +34 -12
- package/src/wallets/phantom/index.ts +7 -2
- package/src/wallets/rabby/index.ts +18 -2
- package/src/wallets/turnkey/index.ts +4 -0
- package/src/wallets/types.ts +2 -1
- package/src/wallets/wallet-connect/index.ts +8 -3
- package/dist/provider-M8-BWFF8.js.map +0 -1
package/dist/types.d.ts
CHANGED
|
@@ -93,7 +93,7 @@ export interface Keychain {
|
|
|
93
93
|
switchChain(rpcUrl: string): Promise<void>;
|
|
94
94
|
openStarterPack(starterpackId: string): void;
|
|
95
95
|
externalDetectWallets(): Promise<ExternalWallet[]>;
|
|
96
|
-
externalConnectWallet(type: ExternalWalletType): Promise<ExternalWalletResponse>;
|
|
96
|
+
externalConnectWallet(type: ExternalWalletType, address?: string): Promise<ExternalWalletResponse>;
|
|
97
97
|
externalSignMessage(type: ExternalWalletType, message: string): Promise<ExternalWalletResponse>;
|
|
98
98
|
externalSignTypedData(type: ExternalWalletType, data: any): Promise<ExternalWalletResponse>;
|
|
99
99
|
externalGetBalance(type: ExternalWalletType, tokenAddress?: string): Promise<ExternalWalletResponse>;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { WalletAdapter, ExternalWallet, ExternalWalletResponse, ExternalWalletType, ExternalPlatform } from '../types';
|
|
2
1
|
import { TypedData } from '@starknet-io/types-js';
|
|
2
|
+
import { ExternalPlatform, ExternalWallet, ExternalWalletResponse, ExternalWalletType, WalletAdapter } from '../types';
|
|
3
3
|
export declare class ArgentWallet implements WalletAdapter {
|
|
4
4
|
readonly type: ExternalWalletType;
|
|
5
5
|
readonly platform: ExternalPlatform;
|
|
6
6
|
private wallet;
|
|
7
7
|
private account;
|
|
8
|
+
private connectedAccounts;
|
|
8
9
|
isAvailable(): boolean;
|
|
9
10
|
getInfo(): ExternalWallet;
|
|
10
11
|
connect(): Promise<ExternalWalletResponse<any>>;
|
|
12
|
+
getConnectedAccounts(): string[];
|
|
11
13
|
signTypedData(data: TypedData): Promise<ExternalWalletResponse<any>>;
|
|
12
14
|
sendTransaction(_txn: any): Promise<ExternalWalletResponse<any>>;
|
|
13
15
|
switchChain(_chainId: string): Promise<boolean>;
|
package/dist/wallets/bridge.d.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { ExternalWallet, ExternalWalletResponse, ExternalWalletType } from './types';
|
|
2
2
|
export declare class WalletBridge {
|
|
3
3
|
private readonly walletAdapters;
|
|
4
|
-
private readonly connectedWalletsByType;
|
|
5
|
-
private readonly connectedWalletsByAddress;
|
|
6
4
|
constructor();
|
|
7
5
|
getIFrameMethods(): {
|
|
8
6
|
externalDetectWallets: (_origin: string) => () => Promise<ExternalWallet[]>;
|
|
9
|
-
externalConnectWallet: (_origin: string) => (type: ExternalWalletType) => Promise<ExternalWalletResponse<unknown>>;
|
|
7
|
+
externalConnectWallet: (_origin: string) => (type: ExternalWalletType, address?: string) => Promise<ExternalWalletResponse<unknown>>;
|
|
10
8
|
externalSignMessage: (_origin: string) => (identifier: ExternalWalletType | string, message: string) => Promise<ExternalWalletResponse<unknown>>;
|
|
11
9
|
externalSignTypedData: (_origin: string) => (identifier: ExternalWalletType | string, data: any) => Promise<ExternalWalletResponse<unknown>>;
|
|
12
10
|
externalSendTransaction: (_origin: string) => (identifier: ExternalWalletType | string, txn: any) => Promise<ExternalWalletResponse<unknown>>;
|
|
@@ -15,7 +13,7 @@ export declare class WalletBridge {
|
|
|
15
13
|
detectWallets(): Promise<ExternalWallet[]>;
|
|
16
14
|
private getWalletAdapterByType;
|
|
17
15
|
private handleError;
|
|
18
|
-
connectWallet(type: ExternalWalletType): Promise<ExternalWalletResponse>;
|
|
16
|
+
connectWallet(type: ExternalWalletType, address?: string): Promise<ExternalWalletResponse>;
|
|
19
17
|
private getConnectedWalletAdapter;
|
|
20
18
|
signMessage(identifier: ExternalWalletType | string, message: string): Promise<ExternalWalletResponse>;
|
|
21
19
|
signTypedData(identifier: ExternalWalletType | string, data: any): Promise<ExternalWalletResponse>;
|
|
@@ -3,12 +3,14 @@ export declare class MetaMaskWallet implements WalletAdapter {
|
|
|
3
3
|
readonly type: ExternalWalletType;
|
|
4
4
|
readonly platform: ExternalPlatform;
|
|
5
5
|
private MMSDK;
|
|
6
|
+
private store;
|
|
6
7
|
private account;
|
|
7
8
|
private connectedAccounts;
|
|
8
9
|
constructor();
|
|
9
10
|
isAvailable(): boolean;
|
|
10
11
|
getInfo(): ExternalWallet;
|
|
11
|
-
connect(): Promise<ExternalWalletResponse<any>>;
|
|
12
|
+
connect(address?: string): Promise<ExternalWalletResponse<any>>;
|
|
13
|
+
getConnectedAccounts(): string[];
|
|
12
14
|
signTransaction(transaction: any): Promise<ExternalWalletResponse<any>>;
|
|
13
15
|
signMessage(message: string): Promise<ExternalWalletResponse<any>>;
|
|
14
16
|
signTypedData(data: any): Promise<ExternalWalletResponse<any>>;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ExternalPlatform, ExternalWallet, ExternalWalletResponse, ExternalWalletType, WalletAdapter } from '../types';
|
|
2
2
|
export declare class PhantomWallet implements WalletAdapter {
|
|
3
3
|
readonly type: ExternalWalletType;
|
|
4
4
|
readonly platform: ExternalPlatform;
|
|
5
5
|
private account;
|
|
6
|
+
private connectedAccounts;
|
|
6
7
|
private getProvider;
|
|
7
8
|
isAvailable(): boolean;
|
|
8
9
|
getInfo(): ExternalWallet;
|
|
9
10
|
connect(): Promise<ExternalWalletResponse<any>>;
|
|
11
|
+
getConnectedAccounts(): string[];
|
|
10
12
|
signMessage(message: string): Promise<ExternalWalletResponse<any>>;
|
|
11
13
|
sendTransaction(serailized_txn: Uint8Array): Promise<ExternalWalletResponse<any>>;
|
|
12
14
|
switchChain(_chainId: string): Promise<boolean>;
|
|
@@ -9,7 +9,8 @@ export declare class RabbyWallet implements WalletAdapter {
|
|
|
9
9
|
constructor();
|
|
10
10
|
isAvailable(): boolean;
|
|
11
11
|
getInfo(): ExternalWallet;
|
|
12
|
-
connect(): Promise<ExternalWalletResponse<any>>;
|
|
12
|
+
connect(address?: string): Promise<ExternalWalletResponse<any>>;
|
|
13
|
+
getConnectedAccounts(): string[];
|
|
13
14
|
signTransaction(transaction: any): Promise<ExternalWalletResponse<any>>;
|
|
14
15
|
signMessage(message: `0x${string}`): Promise<ExternalWalletResponse<any>>;
|
|
15
16
|
signTypedData(data: any): Promise<ExternalWalletResponse<any>>;
|
|
@@ -10,6 +10,7 @@ export declare class TurnkeyWallet implements WalletAdapter {
|
|
|
10
10
|
isAvailable(): boolean;
|
|
11
11
|
getInfo(): ExternalWallet;
|
|
12
12
|
connect(): Promise<ExternalWalletResponse<any>>;
|
|
13
|
+
getConnectedAccounts(): string[];
|
|
13
14
|
signTransaction(transaction: any): Promise<ExternalWalletResponse<any>>;
|
|
14
15
|
signMessage(message: string): Promise<ExternalWalletResponse<any>>;
|
|
15
16
|
signTypedData(data: any): Promise<ExternalWalletResponse<any>>;
|
package/dist/wallets/types.d.ts
CHANGED
|
@@ -21,7 +21,8 @@ export interface WalletAdapter {
|
|
|
21
21
|
platform: ExternalPlatform;
|
|
22
22
|
isAvailable(): boolean;
|
|
23
23
|
getInfo(): ExternalWallet;
|
|
24
|
-
|
|
24
|
+
getConnectedAccounts(): string[];
|
|
25
|
+
connect(address?: string): Promise<ExternalWalletResponse<any>>;
|
|
25
26
|
signMessage?(message: string): Promise<ExternalWalletResponse<any>>;
|
|
26
27
|
signTypedData?(data: any): Promise<ExternalWalletResponse<any>>;
|
|
27
28
|
sendTransaction(tx: any): Promise<ExternalWalletResponse<any>>;
|
|
@@ -5,7 +5,8 @@ export declare class WalletConnectWallet implements WalletAdapter {
|
|
|
5
5
|
readonly type: ExternalWalletType;
|
|
6
6
|
readonly platform: ExternalPlatform;
|
|
7
7
|
private account;
|
|
8
|
-
constructor(provider: Provider,
|
|
8
|
+
constructor(provider: Provider, address?: string);
|
|
9
|
+
getConnectedAccounts(): string[];
|
|
9
10
|
isAvailable(): boolean;
|
|
10
11
|
getInfo(): ExternalWallet;
|
|
11
12
|
connect(): Promise<ExternalWalletResponse<any>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cartridge/controller",
|
|
3
|
-
"version": "0.7.13
|
|
3
|
+
"version": "0.7.13",
|
|
4
4
|
"description": "Cartridge Controller",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"cbor-x": "^1.5.0",
|
|
37
37
|
"mipd": "^0.0.7",
|
|
38
38
|
"@walletconnect/ethereum-provider": "^2.20.0",
|
|
39
|
-
"@cartridge/account-wasm": "0.7.13
|
|
40
|
-
"@cartridge/utils": "0.7.13
|
|
39
|
+
"@cartridge/account-wasm": "0.7.13",
|
|
40
|
+
"@cartridge/utils": "0.7.13"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/jest": "^29.5.14",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"vite-plugin-node-polyfills": "^0.22.0",
|
|
54
54
|
"vite-plugin-top-level-await": "^1.4.4",
|
|
55
55
|
"vite-plugin-wasm": "^3.4.1",
|
|
56
|
-
"@cartridge/tsconfig": "0.7.13
|
|
56
|
+
"@cartridge/tsconfig": "0.7.13"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
59
|
"build:deps": "pnpm build",
|
package/src/types.ts
CHANGED
|
@@ -145,6 +145,7 @@ export interface Keychain {
|
|
|
145
145
|
externalDetectWallets(): Promise<ExternalWallet[]>;
|
|
146
146
|
externalConnectWallet(
|
|
147
147
|
type: ExternalWalletType,
|
|
148
|
+
address?: string,
|
|
148
149
|
): Promise<ExternalWalletResponse>;
|
|
149
150
|
externalSignMessage(
|
|
150
151
|
type: ExternalWalletType,
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
+
import { TypedData } from "@starknet-io/types-js";
|
|
2
|
+
import { connect, StarknetWindowObject } from "starknetkit";
|
|
3
|
+
import { InjectedConnector } from "starknetkit/injected";
|
|
1
4
|
import {
|
|
2
|
-
|
|
5
|
+
ExternalPlatform,
|
|
3
6
|
ExternalWallet,
|
|
4
7
|
ExternalWalletResponse,
|
|
5
8
|
ExternalWalletType,
|
|
6
|
-
|
|
9
|
+
WalletAdapter,
|
|
7
10
|
} from "../types";
|
|
8
|
-
import { connect, StarknetWindowObject } from "starknetkit";
|
|
9
|
-
import { InjectedConnector } from "starknetkit/injected";
|
|
10
|
-
import { TypedData } from "@starknet-io/types-js";
|
|
11
11
|
|
|
12
12
|
export class ArgentWallet implements WalletAdapter {
|
|
13
13
|
readonly type: ExternalWalletType = "argent";
|
|
14
14
|
readonly platform: ExternalPlatform = "starknet";
|
|
15
15
|
private wallet: StarknetWindowObject | undefined = undefined;
|
|
16
16
|
private account: string | undefined = undefined;
|
|
17
|
+
private connectedAccounts: string[] = [];
|
|
17
18
|
|
|
18
19
|
isAvailable(): boolean {
|
|
19
20
|
return typeof window !== "undefined" && !!window.starknet_argentX;
|
|
@@ -65,6 +66,10 @@ export class ArgentWallet implements WalletAdapter {
|
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
getConnectedAccounts(): string[] {
|
|
70
|
+
return this.connectedAccounts;
|
|
71
|
+
}
|
|
72
|
+
|
|
68
73
|
async signTypedData(data: TypedData): Promise<ExternalWalletResponse<any>> {
|
|
69
74
|
try {
|
|
70
75
|
if (!this.isAvailable() || !this.wallet) {
|
package/src/wallets/bridge.ts
CHANGED
|
@@ -11,21 +11,19 @@ import {
|
|
|
11
11
|
|
|
12
12
|
export class WalletBridge {
|
|
13
13
|
private readonly walletAdapters: Map<ExternalWalletType, WalletAdapter>;
|
|
14
|
-
private readonly connectedWalletsByType: Map<
|
|
15
|
-
ExternalWalletType,
|
|
16
|
-
WalletAdapter
|
|
17
|
-
> = new Map();
|
|
18
|
-
private readonly connectedWalletsByAddress: Map<string, WalletAdapter> =
|
|
19
|
-
new Map();
|
|
20
14
|
|
|
21
15
|
constructor() {
|
|
22
16
|
this.walletAdapters = new Map<ExternalWalletType, WalletAdapter>();
|
|
17
|
+
|
|
23
18
|
const metamask = new MetaMaskWallet();
|
|
24
19
|
metamask.isAvailable() && this.walletAdapters.set("metamask", metamask);
|
|
20
|
+
|
|
25
21
|
const phantom = new PhantomWallet();
|
|
26
22
|
phantom.isAvailable() && this.walletAdapters.set("phantom", phantom);
|
|
23
|
+
|
|
27
24
|
const argent = new ArgentWallet();
|
|
28
25
|
argent.isAvailable() && this.walletAdapters.set("argent", argent);
|
|
26
|
+
|
|
29
27
|
const rabby = new RabbyWallet();
|
|
30
28
|
rabby.isAvailable() && this.walletAdapters.set("rabby", rabby);
|
|
31
29
|
|
|
@@ -37,8 +35,9 @@ export class WalletBridge {
|
|
|
37
35
|
getIFrameMethods() {
|
|
38
36
|
return {
|
|
39
37
|
externalDetectWallets: (_origin: string) => () => this.detectWallets(),
|
|
40
|
-
externalConnectWallet:
|
|
41
|
-
|
|
38
|
+
externalConnectWallet:
|
|
39
|
+
(_origin: string) => (type: ExternalWalletType, address?: string) =>
|
|
40
|
+
this.connectWallet(type, address),
|
|
42
41
|
externalSignMessage:
|
|
43
42
|
(_origin: string) =>
|
|
44
43
|
(identifier: ExternalWalletType | string, message: string) =>
|
|
@@ -84,7 +83,7 @@ export class WalletBridge {
|
|
|
84
83
|
error instanceof Error ? error.message : "Unknown error";
|
|
85
84
|
let walletType: ExternalWalletType | string = "unknown";
|
|
86
85
|
if (typeof identifier === "string") {
|
|
87
|
-
const adapter = this.
|
|
86
|
+
const adapter = this.getConnectedWalletAdapter(identifier);
|
|
88
87
|
walletType = responseType ?? adapter?.type ?? identifier;
|
|
89
88
|
} else {
|
|
90
89
|
walletType = identifier;
|
|
@@ -100,14 +99,13 @@ export class WalletBridge {
|
|
|
100
99
|
|
|
101
100
|
async connectWallet(
|
|
102
101
|
type: ExternalWalletType,
|
|
102
|
+
address?: string,
|
|
103
103
|
): Promise<ExternalWalletResponse> {
|
|
104
104
|
try {
|
|
105
105
|
const wallet = this.getWalletAdapterByType(type);
|
|
106
|
-
const response = await wallet.connect();
|
|
106
|
+
const response = await wallet.connect(address);
|
|
107
107
|
|
|
108
108
|
if (response.success && response.account) {
|
|
109
|
-
this.connectedWalletsByType.set(type, wallet);
|
|
110
|
-
this.connectedWalletsByAddress.set(response.account, wallet);
|
|
111
109
|
console.log(
|
|
112
110
|
`Wallet ${type} connected with address ${response.account}`,
|
|
113
111
|
);
|
|
@@ -133,15 +131,22 @@ export class WalletBridge {
|
|
|
133
131
|
): WalletAdapter {
|
|
134
132
|
let wallet: WalletAdapter | undefined;
|
|
135
133
|
if (typeof identifier === "string") {
|
|
136
|
-
|
|
134
|
+
// this is an address
|
|
135
|
+
wallet = this.walletAdapters
|
|
136
|
+
.values()
|
|
137
|
+
.find((adapter) =>
|
|
138
|
+
adapter.getConnectedAccounts().includes(identifier.toLowerCase()),
|
|
139
|
+
);
|
|
137
140
|
} else {
|
|
138
|
-
wallet = this.
|
|
141
|
+
wallet = this.walletAdapters.get(identifier);
|
|
139
142
|
}
|
|
140
143
|
|
|
141
144
|
if (!wallet && typeof identifier === "string") {
|
|
142
|
-
wallet = this.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
+
wallet = this.walletAdapters
|
|
146
|
+
.values()
|
|
147
|
+
.find((adapter) =>
|
|
148
|
+
adapter.getConnectedAccounts().includes(identifier.toLowerCase()),
|
|
149
|
+
);
|
|
145
150
|
}
|
|
146
151
|
|
|
147
152
|
if (!wallet) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MetaMaskSDK } from "@metamask/sdk";
|
|
2
|
+
import { createStore } from "mipd";
|
|
2
3
|
import {
|
|
3
4
|
ExternalPlatform,
|
|
4
5
|
ExternalWallet,
|
|
@@ -11,6 +12,7 @@ export class MetaMaskWallet implements WalletAdapter {
|
|
|
11
12
|
readonly type: ExternalWalletType = "metamask";
|
|
12
13
|
readonly platform: ExternalPlatform = "ethereum";
|
|
13
14
|
private MMSDK: MetaMaskSDK;
|
|
15
|
+
private store = createStore();
|
|
14
16
|
private account: string | undefined = undefined;
|
|
15
17
|
private connectedAccounts: string[] = [];
|
|
16
18
|
|
|
@@ -21,23 +23,35 @@ export class MetaMaskWallet implements WalletAdapter {
|
|
|
21
23
|
url: window.location.href,
|
|
22
24
|
},
|
|
23
25
|
});
|
|
24
|
-
this.
|
|
25
|
-
this.MMSDK.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
if (this.isAvailable()) {
|
|
27
|
+
this.MMSDK.sdkInitPromise?.then(() => {
|
|
28
|
+
this.MMSDK.getProvider()
|
|
29
|
+
?.request({
|
|
30
|
+
method: "eth_accounts",
|
|
31
|
+
})
|
|
32
|
+
.then((accounts: any) => {
|
|
33
|
+
if (accounts && accounts.length > 0) {
|
|
34
|
+
this.account = accounts[0];
|
|
35
|
+
this.connectedAccounts = accounts;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
this.MMSDK.getProvider()?.on("accountsChanged", (accounts: any) => {
|
|
39
|
+
if (Array.isArray(accounts)) {
|
|
40
|
+
this.account = accounts?.[0];
|
|
33
41
|
this.connectedAccounts = accounts;
|
|
34
42
|
}
|
|
35
43
|
});
|
|
36
|
-
|
|
44
|
+
});
|
|
45
|
+
}
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
isAvailable(): boolean {
|
|
40
|
-
return
|
|
49
|
+
return (
|
|
50
|
+
typeof window !== "undefined" &&
|
|
51
|
+
this.store
|
|
52
|
+
.getProviders()
|
|
53
|
+
.some((provider) => provider.info.rdns === "io.metamask")
|
|
54
|
+
);
|
|
41
55
|
}
|
|
42
56
|
|
|
43
57
|
getInfo(): ExternalWallet {
|
|
@@ -54,7 +68,11 @@ export class MetaMaskWallet implements WalletAdapter {
|
|
|
54
68
|
};
|
|
55
69
|
}
|
|
56
70
|
|
|
57
|
-
async connect(): Promise<ExternalWalletResponse<any>> {
|
|
71
|
+
async connect(address?: string): Promise<ExternalWalletResponse<any>> {
|
|
72
|
+
if (address && this.connectedAccounts.includes(address)) {
|
|
73
|
+
this.account = address;
|
|
74
|
+
}
|
|
75
|
+
|
|
58
76
|
if (this.account) {
|
|
59
77
|
return { success: true, wallet: this.type, account: this.account };
|
|
60
78
|
}
|
|
@@ -82,6 +100,10 @@ export class MetaMaskWallet implements WalletAdapter {
|
|
|
82
100
|
}
|
|
83
101
|
}
|
|
84
102
|
|
|
103
|
+
getConnectedAccounts(): string[] {
|
|
104
|
+
return this.connectedAccounts;
|
|
105
|
+
}
|
|
106
|
+
|
|
85
107
|
async signTransaction(
|
|
86
108
|
transaction: any,
|
|
87
109
|
): Promise<ExternalWalletResponse<any>> {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { PublicKey, Transaction, VersionedTransaction } from "@solana/web3.js";
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
ExternalPlatform,
|
|
4
4
|
ExternalWallet,
|
|
5
5
|
ExternalWalletResponse,
|
|
6
6
|
ExternalWalletType,
|
|
7
|
-
|
|
7
|
+
WalletAdapter,
|
|
8
8
|
} from "../types";
|
|
9
9
|
|
|
10
10
|
interface PhantomProvider {
|
|
@@ -38,6 +38,7 @@ export class PhantomWallet implements WalletAdapter {
|
|
|
38
38
|
readonly type: ExternalWalletType = "phantom";
|
|
39
39
|
readonly platform: ExternalPlatform = "solana";
|
|
40
40
|
private account: string | undefined = undefined;
|
|
41
|
+
private connectedAccounts: string[] = [];
|
|
41
42
|
|
|
42
43
|
private getProvider(): PhantomProvider {
|
|
43
44
|
if (typeof window === "undefined") {
|
|
@@ -96,6 +97,10 @@ export class PhantomWallet implements WalletAdapter {
|
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
|
|
100
|
+
getConnectedAccounts(): string[] {
|
|
101
|
+
return this.connectedAccounts;
|
|
102
|
+
}
|
|
103
|
+
|
|
99
104
|
async signMessage(message: string): Promise<ExternalWalletResponse<any>> {
|
|
100
105
|
try {
|
|
101
106
|
if (!this.isAvailable() || !this.account) {
|
|
@@ -28,6 +28,15 @@ export class RabbyWallet implements WalletAdapter {
|
|
|
28
28
|
.then((accounts) => {
|
|
29
29
|
this.connectedAccounts = accounts;
|
|
30
30
|
});
|
|
31
|
+
this.provider?.provider?.on("accountsChanged", (accounts: string[]) => {
|
|
32
|
+
if (accounts) {
|
|
33
|
+
// rabby doesn't allow multiple accounts to be connected at the same time
|
|
34
|
+
this.connectedAccounts = accounts.map((account) =>
|
|
35
|
+
account.toLowerCase(),
|
|
36
|
+
);
|
|
37
|
+
this.account = accounts?.[0]?.toLowerCase();
|
|
38
|
+
}
|
|
39
|
+
});
|
|
31
40
|
}
|
|
32
41
|
|
|
33
42
|
isAvailable(): boolean {
|
|
@@ -48,7 +57,11 @@ export class RabbyWallet implements WalletAdapter {
|
|
|
48
57
|
};
|
|
49
58
|
}
|
|
50
59
|
|
|
51
|
-
async connect(): Promise<ExternalWalletResponse<any>> {
|
|
60
|
+
async connect(address?: string): Promise<ExternalWalletResponse<any>> {
|
|
61
|
+
if (address && this.connectedAccounts.includes(address.toLowerCase())) {
|
|
62
|
+
this.account = address.toLowerCase();
|
|
63
|
+
}
|
|
64
|
+
|
|
52
65
|
if (this.account) {
|
|
53
66
|
return { success: true, wallet: this.type, account: this.account };
|
|
54
67
|
}
|
|
@@ -78,6 +91,10 @@ export class RabbyWallet implements WalletAdapter {
|
|
|
78
91
|
}
|
|
79
92
|
}
|
|
80
93
|
|
|
94
|
+
getConnectedAccounts(): string[] {
|
|
95
|
+
return this.connectedAccounts;
|
|
96
|
+
}
|
|
97
|
+
|
|
81
98
|
async signTransaction(
|
|
82
99
|
transaction: any,
|
|
83
100
|
): Promise<ExternalWalletResponse<any>> {
|
|
@@ -114,7 +131,6 @@ export class RabbyWallet implements WalletAdapter {
|
|
|
114
131
|
if (!this.isAvailable() || !this.account) {
|
|
115
132
|
throw new Error("Rabby is not connected");
|
|
116
133
|
}
|
|
117
|
-
|
|
118
134
|
const result = await this.provider?.provider.request({
|
|
119
135
|
method: "personal_sign",
|
|
120
136
|
params: [this.account!, message] as any,
|
package/src/wallets/types.ts
CHANGED
|
@@ -26,7 +26,8 @@ export interface WalletAdapter {
|
|
|
26
26
|
// Methods
|
|
27
27
|
isAvailable(): boolean;
|
|
28
28
|
getInfo(): ExternalWallet;
|
|
29
|
-
|
|
29
|
+
getConnectedAccounts(): string[];
|
|
30
|
+
connect(address?: string): Promise<ExternalWalletResponse<any>>;
|
|
30
31
|
signMessage?(message: string): Promise<ExternalWalletResponse<any>>;
|
|
31
32
|
signTypedData?(data: any): Promise<ExternalWalletResponse<any>>;
|
|
32
33
|
sendTransaction(tx: any): Promise<ExternalWalletResponse<any>>;
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
WalletAdapter,
|
|
8
8
|
} from "../types";
|
|
9
9
|
|
|
10
|
+
// TODO(tedison): move wallet to inside the keychain
|
|
10
11
|
export class WalletConnectWallet implements WalletAdapter {
|
|
11
12
|
readonly type: ExternalWalletType = "walletconnect" as ExternalWalletType;
|
|
12
13
|
readonly platform: ExternalPlatform = "ethereum";
|
|
@@ -14,9 +15,13 @@ export class WalletConnectWallet implements WalletAdapter {
|
|
|
14
15
|
|
|
15
16
|
constructor(
|
|
16
17
|
private provider: Provider,
|
|
17
|
-
|
|
18
|
+
address?: string,
|
|
18
19
|
) {
|
|
19
|
-
this.account =
|
|
20
|
+
this.account = address?.toLowerCase();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
getConnectedAccounts(): string[] {
|
|
24
|
+
return this.account ? [this.account] : [];
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
isAvailable(): boolean {
|
|
@@ -100,7 +105,7 @@ export class WalletConnectWallet implements WalletAdapter {
|
|
|
100
105
|
|
|
101
106
|
const result = await this.provider.request({
|
|
102
107
|
method: "personal_sign",
|
|
103
|
-
params: [this.account
|
|
108
|
+
params: [message, this.account!],
|
|
104
109
|
});
|
|
105
110
|
|
|
106
111
|
return { success: true, wallet: this.type, result };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"provider-M8-BWFF8.js","sources":["../src/types.ts","../src/utils.ts","../src/constants.ts","../src/errors.ts","../../../node_modules/.pnpm/@starknet-io+types-js@0.7.10/node_modules/@starknet-io/types-js/dist/esm/wallet-api/constants.js","../src/icon.ts","../src/mutex.ts","../src/provider.ts"],"sourcesContent":["import {\n constants,\n BigNumberish,\n Call,\n Abi,\n InvocationsDetails,\n} from \"starknet\";\nimport {\n AddInvokeTransactionResult,\n ChainId,\n Signature,\n TypedData,\n} from \"@starknet-io/types-js\";\nimport { KeychainIFrame, ProfileIFrame } from \"./iframe\";\nimport { Policy, SessionPolicies } from \"@cartridge/presets\";\nimport {\n ExternalWallet,\n ExternalWalletResponse,\n ExternalWalletType,\n} from \"./wallets/types\";\n\nexport type Session = {\n chainId: constants.StarknetChainId;\n policies: Policy[];\n maxFee: BigNumberish;\n expiresAt: bigint;\n credentials: {\n authorization: string[];\n privateKey: string;\n };\n};\n\nexport enum ResponseCodes {\n SUCCESS = \"SUCCESS\",\n NOT_CONNECTED = \"NOT_CONNECTED\",\n ERROR = \"ERROR\",\n CANCELED = \"CANCELED\",\n USER_INTERACTION_REQUIRED = \"USER_INTERACTION_REQUIRED\",\n}\n\nexport type ConnectError = {\n code: ResponseCodes;\n message: string;\n error?: ControllerError;\n};\n\nexport type ControllerError = {\n code: Number;\n message: string;\n data?: any;\n};\n\nexport type ConnectReply = {\n code: ResponseCodes.SUCCESS;\n address: string;\n policies?: SessionPolicies;\n};\n\nexport type ExecuteReply =\n | (AddInvokeTransactionResult & {\n code: ResponseCodes.SUCCESS;\n })\n | {\n code: ResponseCodes.USER_INTERACTION_REQUIRED;\n };\n\nexport type ProbeReply = {\n code: ResponseCodes.SUCCESS;\n address: string;\n rpcUrl?: string;\n};\n\nexport type DeployReply = {\n code: ResponseCodes.SUCCESS;\n transaction_hash: string;\n};\n\nexport type IFrames = {\n keychain: KeychainIFrame;\n profile?: ProfileIFrame;\n version?: number;\n};\n\nexport interface LookupRequest {\n usernames?: string[];\n addresses?: string[];\n}\n\nexport interface LookupResult {\n username: string;\n addresses: string[];\n}\n\nexport interface LookupResponse {\n results: LookupResult[];\n}\n\nexport enum FeeSource {\n PAYMASTER = \"PAYMASTER\",\n CREDITS = \"CREDITS\",\n}\n\ntype ContractAddress = string;\ntype CartridgeID = string;\nexport type ControllerAccounts = Record<ContractAddress, CartridgeID>;\n\nexport interface Keychain {\n probe(rpcUrl: string): Promise<ProbeReply | ConnectError>;\n connect(\n policies: SessionPolicies,\n rpcUrl: string,\n ): Promise<ConnectReply | ConnectError>;\n disconnect(): void;\n\n reset(): void;\n revoke(origin: string): void;\n\n deploy(): Promise<DeployReply | ConnectError>;\n execute(\n calls: Call | Call[],\n abis?: Abi[],\n transactionsDetail?: InvocationsDetails,\n sync?: boolean,\n feeSource?: any,\n error?: ControllerError,\n ): Promise<ExecuteReply | ConnectError>;\n signMessage(\n typedData: TypedData,\n account: string,\n async?: boolean,\n ): Promise<Signature | ConnectError>;\n openSettings(): Promise<void | ConnectError>;\n session(): Promise<Session>;\n sessions(): Promise<{\n [key: string]: Session;\n }>;\n delegateAccount(): string;\n username(): string;\n openPurchaseCredits(): void;\n openExecute(calls: Call[]): Promise<void>;\n switchChain(rpcUrl: string): Promise<void>;\n openStarterPack(starterpackId: string): void;\n\n // External wallet methods\n externalDetectWallets(): Promise<ExternalWallet[]>;\n externalConnectWallet(\n type: ExternalWalletType,\n ): Promise<ExternalWalletResponse>;\n externalSignMessage(\n type: ExternalWalletType,\n message: string,\n ): Promise<ExternalWalletResponse>;\n externalSignTypedData(\n type: ExternalWalletType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n data: any,\n ): Promise<ExternalWalletResponse>;\n externalGetBalance(\n type: ExternalWalletType,\n tokenAddress?: string,\n ): Promise<ExternalWalletResponse>;\n}\n\nexport interface Profile {\n navigate(path: string): void;\n switchChain(rpcUrl: string): Promise<void>;\n}\n\nexport interface Modal {\n open: () => void;\n close: () => void;\n}\n\n/**\n * Options for configuring the controller\n */\nexport type ControllerOptions = ProviderOptions &\n KeychainOptions &\n ProfileOptions;\n\nexport type IFrameOptions = {\n /** The ID of the starter pack to use */\n starterPackId?: string;\n /** The preset to use */\n preset?: string;\n};\n\nexport type Chain = {\n rpcUrl: string;\n};\n\nexport type ProviderOptions = {\n defaultChainId: ChainId;\n chains: Chain[];\n};\n\nexport type KeychainOptions = IFrameOptions & {\n policies?: SessionPolicies;\n /** The URL of keychain */\n url?: string;\n /** The origin of keychain */\n origin?: string;\n /** Propagate transaction errors back to caller instead of showing modal */\n propagateSessionErrors?: boolean;\n /** The fee source to use for execute from outside */\n feeSource?: FeeSource;\n};\n\nexport type ProfileOptions = IFrameOptions & {\n /** The URL of profile. Mainly for internal development purpose */\n profileUrl?: string;\n /** The project name of Slot instance. */\n slot?: string;\n /** The namespace to use to fetch trophies data from indexer. Will be mandatory once profile page is in production */\n namespace?: string;\n /** The tokens to be listed on Inventory modal */\n tokens?: Tokens;\n /** The policies to use for the profile */\n policies?: SessionPolicies;\n};\n\nexport type ProfileContextTypeVariant =\n | \"inventory\"\n | \"trophies\"\n | \"achievements\"\n | \"leaderboard\"\n | \"activity\";\n\nexport type Tokens = {\n erc20?: string[];\n};\n","import {\n addAddressPadding,\n Call,\n CallData,\n constants,\n getChecksumAddress,\n hash,\n Provider,\n shortString,\n typedData,\n TypedDataRevision,\n} from \"starknet\";\nimport wasm from \"@cartridge/account-wasm/controller\";\nimport { Policies, SessionPolicies } from \"@cartridge/presets\";\nimport { ChainId } from \"@starknet-io/types-js\";\nimport { ParsedSessionPolicies } from \"./policies\";\n\n// Whitelist of allowed property names to prevent prototype pollution\nconst ALLOWED_PROPERTIES = new Set([\n \"contracts\",\n \"messages\",\n \"target\",\n \"method\",\n \"name\",\n \"description\",\n \"types\",\n \"domain\",\n \"primaryType\",\n]);\n\nconst LOCAL_HOSTNAMES = [\"localhost\", \"127.0.0.1\", \"0.0.0.0\"];\n\nfunction validatePropertyName(prop: string): void {\n if (!ALLOWED_PROPERTIES.has(prop)) {\n throw new Error(`Invalid property name: ${prop}`);\n }\n}\n\nfunction safeObjectAccess<T>(obj: any, prop: string): T {\n validatePropertyName(prop);\n return obj[prop];\n}\n\nexport function normalizeCalls(calls: Call | Call[]) {\n return toArray(calls).map((call) => {\n return {\n entrypoint: call.entrypoint,\n contractAddress: addAddressPadding(call.contractAddress),\n calldata: CallData.toHex(call.calldata),\n };\n });\n}\n\nexport function toSessionPolicies(policies: Policies): SessionPolicies {\n return Array.isArray(policies)\n ? policies.reduce<SessionPolicies>(\n (prev, p) => {\n if (safeObjectAccess<string>(p, \"target\")) {\n const target = getChecksumAddress(\n safeObjectAccess<string>(p, \"target\"),\n );\n const entrypoint = safeObjectAccess<string>(p, \"method\");\n const contracts = safeObjectAccess<Record<string, any>>(\n prev,\n \"contracts\",\n );\n const item = {\n name: humanizeString(entrypoint),\n entrypoint: entrypoint,\n description: safeObjectAccess<string>(p, \"description\"),\n };\n\n if (target in contracts) {\n const methods = toArray(contracts[target].methods);\n contracts[target] = {\n methods: [...methods, item],\n };\n } else {\n contracts[target] = {\n methods: [item],\n };\n }\n } else {\n const messages = safeObjectAccess<any[]>(prev, \"messages\");\n messages.push(p);\n }\n\n return prev;\n },\n { contracts: {}, messages: [] },\n )\n : policies;\n}\n\nexport function toWasmPolicies(policies: ParsedSessionPolicies): wasm.Policy[] {\n return [\n ...Object.entries(policies.contracts ?? {}).flatMap(\n ([target, { methods }]) =>\n toArray(methods).map((m) => ({\n target,\n method: m.entrypoint,\n authorized: m.authorized,\n })),\n ),\n ...(policies.messages ?? []).map((p) => {\n const domainHash = typedData.getStructHash(\n p.types,\n \"StarknetDomain\",\n p.domain,\n TypedDataRevision.ACTIVE,\n );\n const typeHash = typedData.getTypeHash(\n p.types,\n p.primaryType,\n TypedDataRevision.ACTIVE,\n );\n\n return {\n scope_hash: hash.computePoseidonHash(domainHash, typeHash),\n authorized: p.authorized,\n };\n }),\n ];\n}\n\nexport function toArray<T>(val: T | T[]): T[] {\n return Array.isArray(val) ? val : [val];\n}\n\nexport function humanizeString(str: string): string {\n return (\n str\n // Convert from camelCase or snake_case\n .replace(/([a-z])([A-Z])/g, \"$1 $2\") // camelCase to spaces\n .replace(/_/g, \" \") // snake_case to spaces\n .toLowerCase()\n // Capitalize first letter\n .replace(/^\\w/, (c) => c.toUpperCase())\n );\n}\n\nexport async function parseChainId(url: URL): Promise<ChainId> {\n const parts = url.pathname.split(\"/\");\n\n if (parts.includes(\"starknet\")) {\n if (parts.includes(\"mainnet\")) {\n return constants.StarknetChainId.SN_MAIN;\n } else if (parts.includes(\"sepolia\")) {\n return constants.StarknetChainId.SN_SEPOLIA;\n }\n } else if (parts.length >= 3) {\n const projectName = parts[2];\n if (parts.includes(\"katana\")) {\n return shortString.encodeShortString(\n `WP_${projectName.toUpperCase().replace(/-/g, \"_\")}`,\n ) as ChainId;\n } else if (parts.includes(\"mainnet\")) {\n return shortString.encodeShortString(\n `GG_${projectName.toUpperCase().replace(/-/g, \"_\")}`,\n ) as ChainId;\n }\n }\n\n if (LOCAL_HOSTNAMES.includes(url.hostname)) {\n const provider = new Provider({\n nodeUrl: url.toString(),\n });\n return await provider.getChainId();\n }\n\n throw new Error(`Chain ${url.toString()} not supported`);\n}\n","export const KEYCHAIN_URL = \"https://x.cartridge.gg\";\nexport const PROFILE_URL = \"https://profile.cartridge.gg\";\nexport const API_URL = \"https://api.cartridge.gg\";\n","export class NotReadyToConnect extends Error {\n constructor() {\n super(\"Not ready to connect\");\n\n Object.setPrototypeOf(this, NotReadyToConnect.prototype);\n }\n}\n","export const Permission = {\n ACCOUNTS: 'accounts',\n};\n//# sourceMappingURL=constants.js.map","export const icon =\n \"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODAwIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGZpbHRlcj0idXJsKCNmaWx0ZXIwX2RfNTExMl83ODIpIj4KPHBhdGggZD0iTTQ2OS4yMzYgNzBDNDgyLjM5IDcwIDQ5My4wNTMgODAuNjYzIDQ5My4wNTMgOTMuODE2NFYxNDcuMTQ3TDUxNS4zMzggMTQ3LjE0N0w1MTUuNDI4IDE0Ny4xNDdMNTE1LjU1NCAxNDcuMTQ3TDUxNS44MjYgMTQ3LjE0OUM1MTYuMDE2IDE0Ny4xNTEgNTE2LjIyNSAxNDcuMTUzIDUxNi40NTEgMTQ3LjE1N0M1MTYuOTA0IDE0Ny4xNjQgNTE3LjQyOCAxNDcuMTc2IDUxOC4wMiAxNDcuMTk1QzUxOS4yMDEgMTQ3LjIzNCA1MjAuNjYgMTQ3LjMwNCA1MjIuMzYxIDE0Ny40MjRDNTI1Ljc0MSAxNDcuNjYzIDUzMC4xODUgMTQ4LjExNCA1MzUuMzYzIDE0OC45NjlDNTQ1LjAwMSAxNTAuNTYyIDU1OC41NTYgMTUzLjc4IDU3Mi45MTggMTYwLjYwM0w3MzAuNDIgMjI2LjY3MUw3MzIuMTAxIDIyNy41MDVDNzcxLjc4NyAyNDcuMTc3IDc4OS45OTMgMjg2LjI5NiA3ODkuOTkzIDMyMi4wMzZWNTg1Ljg2NUM3ODkuOTkzIDU4Ni4wNTQgNzg5Ljk5NCA1ODYuMjU0IDc4OS45OTQgNTg2LjQ2M0w3ODkuOTk2IDU4Ni45MTNDNzkwLjAzOCA1OTcuMDk2IDc5MC4xNjEgNjI2Ljk5NiA3NjQuMjMxIDY1Mi44MjNMNzE0Ljc2IDcwMi4wOTVMNzE0LjY0MSA3MDIuMjE1QzcwNC42MDEgNzEyLjI3NSA2OTIuMTIzIDcyMC42NTIgNjc2LjI4NCA3MjQuODc5QzY2NC4zOSA3MjguMDU0IDY1Mi44MjcgNzI3Ljk2NiA2NDguNjM3IDcyNy45MzRMNjQ4LjYxOSA3MjcuOTMzQzY0OC40MDkgNzI3LjkzMiA2NDguMjE5IDcyNy45MyA2NDguMDQ3IDcyNy45M0w2NDcuNzUyIDcyNy45MjlINDgwLjcyMUM0NzQuMDk0IDcyNy45MjkgNDY4LjcyMSA3MjIuNTU2IDQ2OC43MjEgNzE1LjkyOVY2NjguMzg4SDMyOC41ODZDMzI4LjU4NiA2NzIuNjI5IDMyOC41NzIgNjk4LjA1MiAzMjguNTYxIDcxNS45NDRDMzI4LjU1NyA3MjIuNTY5IDMyMy4xODYgNzI3LjkyOSAzMTYuNTYxIDcyNy45MjlIMTUyLjI0NkMxNTIuMTA0IDcyNy45MjkgMTUxLjk0MiA3MjcuOTI5IDE1MS43NjIgNzI3LjkzMUwxNTEuMzYyIDcyNy45MzRDMTQ3LjE3MiA3MjcuOTY2IDEzNS42MDkgNzI4LjA1NCAxMjMuNzE0IDcyNC44NzlDMTA3Ljg3MyA3MjAuNjUxIDk1LjM5MzggNzEyLjI3MiA4NS4zNTI5IDcwMi4yMUw4NS4yMzg2IDcwMi4wOTVMMzUuNjcgNjUyLjcyNUwzNS41NzIzIDY1Mi42MjdDOS44NjI0MiA2MjYuNzggOS45NjY3IDU5Ny4xODUgMTAuMDAzIDU4Ni44NzRDMTAuMDA0MyA1ODYuNTEzIDEwLjAwNTUgNTg2LjE3NyAxMC4wMDU1IDU4NS44NjVWMzIyLjAzNkMxMC4wMDU1IDI4Ni40MyAyOC4xNjYyIDI0Ny4xOTkgNjcuODk3NyAyMjcuNTA1TDY5LjU3OSAyMjYuNjcxTDIyNy4wODEgMTYwLjYwM0MyNDEuNDQzIDE1My43OCAyNTQuOTk4IDE1MC41NjIgMjY0LjYzNiAxNDguOTY5QzI2OS44MTQgMTQ4LjExNCAyNzQuMjU4IDE0Ny42NjMgMjc3LjYzOCAxNDcuNDI0QzI3OS4zMzggMTQ3LjMwNCAyODAuNzk4IDE0Ny4yMzQgMjgxLjk3OSAxNDcuMTk1QzI4Mi41NzEgMTQ3LjE3NiAyODMuMDk1IDE0Ny4xNjQgMjgzLjU0NyAxNDcuMTU3TDI4My45MTcgMTQ3LjE1MkwyODQuMTczIDE0Ny4xNDlMMjg0LjQ0NSAxNDcuMTQ3TDI4NC41NzEgMTQ3LjE0N0wyODQuNjYgMTQ3LjE0N0wzMDYuOTQyIDE0Ny4xNDdWOTMuODE2NEMzMDYuOTQyIDgwLjY2MyAzMTcuNjA1IDcwIDMzMC43NTggNzBINDY5LjIzNloiIGZpbGw9IiMxOTFBMUEiLz4KPHBhdGggZD0iTTM2Ni40ODMgMTI5LjU0SDQzMy41MTJWMjA2LjY4N0gzNjYuNDgzVjEyOS41NFoiIGZpbGw9IiNGQkNCNEEiLz4KPHBhdGggZD0iTTI2OS4wMSA2MDIuNDI5SDE0NC4wMDhDMTM1Ljc2OCA2MDIuNDI5IDEzNS43NjggNTk0LjE0NiAxMzUuNzY4IDU5NC4xNDZWMjgwLjg1QzEzNS43NjggMjgwLjg1IDEzNS43NjggMjcyLjY0NCAxNDQuMDA4IDI3Mi42NDRIMzY2LjQ4M0wzNjYuNDgzIDIwNi42ODdIMjg0LjY5QzI4NC42OSAyMDYuNjg3IDI2OC4xMzQgMjA2LjY4NyAyNTEuNTc5IDIxNC44OTNMOTQuMzQxNCAyODAuODVDNzcuNzg2MSAyODkuMDU3IDY5LjU0NjkgMzA1LjYyMyA2OS41NDY5IDMyMi4wMzVWNTg1Ljg2M0M2OS41NDY5IDU5NC4xNDcgNjkuNTQ2OSA2MDIuMzUzIDc3Ljc4NjEgNjEwLjYzNkwxMjcuNDUyIDY2MC4xMDRDMTM1LjY5MSA2NjguMzg3IDE0MS45MjggNjY4LjM4NyAxNTIuMjQ3IDY2OC4zODdIMjY5LjAyOUMyNjkuMDM3IDY0OC4zNCAyNjkuMDQ2IDYyNC42NTUgMjY5LjA1NCA2MDIuODg3SDUyOC4wMTNWNjY4LjM4N0g2NDcuNzUzQzY1OC4wNzEgNjY4LjM4NyA2NjQuMzA4IDY2OC4zODcgNjcyLjU0NyA2NjAuMTA0TDcyMi4yMTMgNjEwLjYzNkM3MzAuNDUzIDYwMi40MjkgNzMwLjQ1MyA1OTQuMTQ3IDczMC40NTMgNTg1Ljg2M1YzMjIuMDM1QzczMC40NTMgMzA1LjU0NiA3MjIuMjEzIDI4OS4wNTcgNzA1LjY1OCAyODAuODVMNTQ4LjQyMSAyMTQuODkzQzUzMS44NjUgMjA2LjY4NyA1MTUuMzEgMjA2LjY4NyA1MTUuMzEgMjA2LjY4N0g0MzMuNTEyTDQzMy41MTIgMjcyLjY0NEg2NTYuMDY5QzY2NC4zMDggMjcyLjY0NCA2NjQuMzA4IDI4MC44NSA2NjQuMzA4IDI4MC44NVY1OTQuMTQ2QzY2NC4zMDggNTk0LjE0NiA2NjQuMzA4IDYwMi40MjkgNjU2LjA2OSA2MDIuNDI5SDUyOC4yNjJWNTM3LjM5NkgyNjkuMDc1QzI2OS4wNzUgNTQzLjcwNyAyNjkuMDE3IDU5Ni45MTIgMjY5LjAxIDYwMi40MjlaIiBmaWxsPSIjRkJDQjRBIi8+CjxwYXRoIGQ9Ik0yNjkuMDA5IDQzNi4xNzJINTI4LjI2MlYzNzAuNjgxSDI2OS4wNzVDMjY5LjA3NSAzNzcuMzczIDI2OS4wMDkgNDM2Ljc4OCAyNjkuMDA5IDQzNi4xNzJaIiBmaWxsPSIjRkJDQjRBIi8+CjwvZz4KPGRlZnM+CjxmaWx0ZXIgaWQ9ImZpbHRlcjBfZF81MTEyXzc4MiIgeD0iLTQiIHk9IjAiIHdpZHRoPSI4MDgiIGhlaWdodD0iODA4IiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+CjxmZUNvbG9yTWF0cml4IGluPSJTb3VyY2VBbHBoYSIgdHlwZT0ibWF0cml4IiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDEyNyAwIiByZXN1bHQ9ImhhcmRBbHBoYSIvPgo8ZmVPZmZzZXQgZHk9IjQiLz4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMiIvPgo8ZmVDb21wb3NpdGUgaW4yPSJoYXJkQWxwaGEiIG9wZXJhdG9yPSJvdXQiLz4KPGZlQ29sb3JNYXRyaXggdHlwZT0ibWF0cml4IiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAuMjUgMCIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9ImVmZmVjdDFfZHJvcFNoYWRvd181MTEyXzc4MiIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9ImVmZmVjdDFfZHJvcFNoYWRvd181MTEyXzc4MiIgcmVzdWx0PSJzaGFwZSIvPgo8L2ZpbHRlcj4KPC9kZWZzPgo8L3N2Zz4K\";\n","function releaseStub() {}\n\n/**\n * A simple mutual exclusion lock. It allows you to obtain and release a lock,\n * ensuring that only one task can access a critical section at a time.\n */\nexport class Mutex {\n private m_lastPromise: Promise<void> = Promise.resolve();\n\n /**\n * Acquire lock\n * @param [bypass=false] option to skip lock acquisition\n */\n public async obtain(bypass = false): Promise<() => void> {\n let release = releaseStub;\n if (bypass) return release;\n const lastPromise = this.m_lastPromise;\n this.m_lastPromise = new Promise<void>((resolve) => (release = resolve));\n await lastPromise;\n return release;\n }\n}\n","import { WalletAccount } from \"starknet\";\nimport {\n AddInvokeTransactionParameters,\n AddStarknetChainParameters,\n Errors,\n Permission,\n RequestAccountsParameters,\n RequestFn,\n StarknetWindowObject,\n SwitchStarknetChainParameters,\n TypedData,\n WalletEventHandlers,\n WalletEventListener,\n WalletEvents,\n} from \"@starknet-io/types-js\";\nimport manifest from \"../package.json\";\n\nimport { icon } from \"./icon\";\nimport { Mutex } from \"./mutex\";\n\nconst mutex = new Mutex();\n\nexport default abstract class BaseProvider implements StarknetWindowObject {\n public id = \"controller\";\n public name = \"Controller\";\n public version = manifest.version;\n public icon = icon;\n\n public account?: WalletAccount;\n public subscriptions: WalletEvents[] = [];\n\n private _probePromise: Promise<WalletAccount | undefined> | null = null;\n\n protected async safeProbe(): Promise<WalletAccount | undefined> {\n // If we already have an account, return it\n if (this.account) {\n return this.account;\n }\n\n // If we're already probing, wait for the existing probe\n if (this._probePromise) {\n return this._probePromise;\n }\n\n const release = await mutex.obtain();\n return await new Promise<WalletAccount | undefined>(async (resolve) => {\n try {\n this._probePromise = this.probe();\n const result = await this._probePromise;\n resolve(result);\n } finally {\n this._probePromise = null;\n }\n }).finally(() => {\n release();\n });\n }\n\n request: RequestFn = async (call) => {\n switch (call.type) {\n case \"wallet_getPermissions\":\n await this.safeProbe();\n\n if (this.account) {\n return [Permission.ACCOUNTS];\n }\n\n return [];\n\n case \"wallet_requestAccounts\": {\n if (this.account) {\n return [this.account.address];\n }\n\n const silentMode =\n call.params && (call.params as RequestAccountsParameters).silent_mode;\n\n this.account = await this.safeProbe();\n\n if (!this.account && !silentMode) {\n this.account = await this.connect();\n }\n\n if (this.account) {\n return [this.account.address];\n }\n\n return [];\n }\n\n case \"wallet_watchAsset\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_watchAsset not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_addStarknetChain\": {\n let params = call.params as AddStarknetChainParameters;\n return this.addStarknetChain(params);\n }\n\n case \"wallet_switchStarknetChain\": {\n let params = call.params as SwitchStarknetChainParameters;\n return this.switchStarknetChain(params.chainId);\n }\n\n case \"wallet_requestChainId\":\n if (!this.account) {\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"Account not initialized\",\n } as Errors.UNEXPECTED_ERROR;\n }\n\n return await this.account.getChainId();\n\n case \"wallet_deploymentData\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_deploymentData not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_addInvokeTransaction\":\n if (!this.account) {\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"Account not initialized\",\n } as Errors.UNEXPECTED_ERROR;\n }\n\n let params = call.params as AddInvokeTransactionParameters;\n return await this.account.execute(\n params.calls.map((call) => ({\n contractAddress: call.contract_address,\n entrypoint: call.entry_point,\n calldata: call.calldata,\n })),\n );\n\n case \"wallet_addDeclareTransaction\":\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"wallet_addDeclareTransaction not implemented\",\n } as Errors.UNEXPECTED_ERROR;\n\n case \"wallet_signTypedData\": {\n if (!this.account) {\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: \"Account not initialized\",\n } as Errors.UNEXPECTED_ERROR;\n }\n\n return await this.account.signMessage(call.params as TypedData);\n }\n\n case \"wallet_supportedSpecs\":\n return [];\n case \"wallet_supportedWalletApi\":\n return [];\n default:\n throw {\n code: 63,\n message: \"An unexpected error occurred\",\n data: `Unknown RPC call type: ${call.type}`,\n } as Errors.UNEXPECTED_ERROR;\n }\n };\n\n on: WalletEventListener = <E extends keyof WalletEventHandlers>(\n event: E,\n handler: WalletEventHandlers[E],\n ): void => {\n if (event !== \"accountsChanged\" && event !== \"networkChanged\") {\n throw new Error(`Unknown event: ${event}`);\n }\n this.subscriptions.push({ type: event, handler } as WalletEvents);\n };\n\n off: WalletEventListener = <E extends keyof WalletEventHandlers>(\n event: E,\n handler: WalletEventHandlers[E],\n ): void => {\n if (event !== \"accountsChanged\" && event !== \"networkChanged\") {\n throw new Error(`Unknown event: ${event}`);\n }\n const idx = this.subscriptions.findIndex(\n (sub) => sub.type === event && sub.handler === handler,\n );\n if (idx >= 0) {\n this.subscriptions.splice(idx, 1);\n }\n };\n\n protected emitNetworkChanged(chainId: string) {\n this.subscriptions\n .filter((sub) => sub.type === \"networkChanged\")\n .forEach((sub) => {\n (sub.handler as WalletEventHandlers[\"networkChanged\"])(chainId);\n });\n }\n\n protected emitAccountsChanged(accounts: string[]) {\n this.subscriptions\n .filter((sub) => sub.type === \"accountsChanged\")\n .forEach((sub) => {\n (sub.handler as WalletEventHandlers[\"accountsChanged\"])(accounts);\n });\n }\n\n abstract probe(): Promise<WalletAccount | undefined>;\n abstract connect(): Promise<WalletAccount | undefined>;\n abstract switchStarknetChain(chainId: string): Promise<boolean>;\n abstract addStarknetChain(\n chain: AddStarknetChainParameters,\n ): Promise<boolean>;\n}\n"],"names":["ResponseCodes","FeeSource","ALLOWED_PROPERTIES","LOCAL_HOSTNAMES","validatePropertyName","prop","safeObjectAccess","obj","normalizeCalls","calls","toArray","call","addAddressPadding","CallData","toSessionPolicies","policies","prev","p","target","getChecksumAddress","entrypoint","contracts","item","humanizeString","methods","toWasmPolicies","m","domainHash","typedData","TypedDataRevision","typeHash","hash","val","str","c","parseChainId","url","parts","constants","projectName","shortString","Provider","KEYCHAIN_URL","PROFILE_URL","API_URL","NotReadyToConnect","Permission","icon","releaseStub","Mutex","bypass","release","lastPromise","resolve","mutex","BaseProvider","manifest","result","silentMode","params","event","handler","idx","sub","chainId","accounts"],"mappings":"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","x_google_ignoreList":[4]}
|