@cartridge/controller 0.7.6 → 0.7.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/.turbo/turbo-build$colon$deps.log +23 -23
- package/.turbo/turbo-build.log +28 -28
- package/dist/controller.cjs +472 -3
- package/dist/controller.cjs.map +1 -1
- package/dist/controller.d.cts +1 -1
- package/dist/controller.d.ts +1 -1
- package/dist/controller.js +472 -3
- package/dist/controller.js.map +1 -1
- package/dist/index.cjs +1908 -1214
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -3
- package/dist/index.d.ts +46 -3
- package/dist/index.js +1905 -1215
- 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 -2
- package/dist/node/index.d.ts +2 -2
- package/dist/node/index.js +1 -1
- package/dist/node/index.js.map +1 -1
- package/dist/{provider-CTDncg8U.d.cts → provider-BeCgS86X.d.cts} +64 -1
- package/dist/{provider-CTDncg8U.d.ts → provider-BeCgS86X.d.ts} +64 -1
- package/dist/session/index.cjs +1 -1
- package/dist/session/index.cjs.map +1 -1
- package/dist/session/index.d.cts +2 -2
- package/dist/session/index.d.ts +2 -2
- package/dist/session/index.js +1 -1
- package/dist/session/index.js.map +1 -1
- package/package.json +8 -5
- package/src/iframe/base.ts +1 -1
- package/src/iframe/keychain.ts +11 -0
- package/src/index.ts +1 -0
- package/src/types.ts +24 -0
- package/src/wallets/argent/index.ts +122 -0
- package/src/wallets/bridge.ts +165 -0
- package/src/wallets/index.ts +5 -0
- package/src/wallets/metamask/index.ts +210 -0
- package/src/wallets/phantom/index.ts +124 -0
- package/src/wallets/types.ts +32 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ExternalWalletType,
|
|
3
|
+
WalletAdapter,
|
|
4
|
+
ExternalWallet,
|
|
5
|
+
ExternalWalletResponse,
|
|
6
|
+
} from "./types";
|
|
7
|
+
import { MetaMaskWallet } from "./metamask";
|
|
8
|
+
import { PhantomWallet } from "./phantom";
|
|
9
|
+
import { ArgentWallet } from "./argent";
|
|
10
|
+
|
|
11
|
+
export class WalletBridge {
|
|
12
|
+
private readonly walletAdapters: Map<ExternalWalletType, WalletAdapter>;
|
|
13
|
+
private readonly connectedWallets: Map<ExternalWalletType, WalletAdapter> =
|
|
14
|
+
new Map();
|
|
15
|
+
|
|
16
|
+
constructor() {
|
|
17
|
+
this.walletAdapters = new Map<ExternalWalletType, WalletAdapter>();
|
|
18
|
+
this.walletAdapters.set("metamask", new MetaMaskWallet());
|
|
19
|
+
this.walletAdapters.set("phantom", new PhantomWallet());
|
|
20
|
+
this.walletAdapters.set("argent", new ArgentWallet());
|
|
21
|
+
|
|
22
|
+
if (typeof window !== "undefined") {
|
|
23
|
+
window.wallet_bridge = this;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getIFrameMethods() {
|
|
28
|
+
return {
|
|
29
|
+
externalDetectWallets: (_origin: string) => () => this.detectWallets(),
|
|
30
|
+
externalConnectWallet: (_origin: string) => (type: ExternalWalletType) =>
|
|
31
|
+
this.connectWallet(type),
|
|
32
|
+
externalSignMessage:
|
|
33
|
+
(_origin: string) => (type: ExternalWalletType, message: string) =>
|
|
34
|
+
this.signMessage(type, message),
|
|
35
|
+
externalSignTypedData:
|
|
36
|
+
(_origin: string) => (type: ExternalWalletType, data: any) =>
|
|
37
|
+
this.signTypedData(type, data),
|
|
38
|
+
externalGetBalance:
|
|
39
|
+
(_origin: string) =>
|
|
40
|
+
(type: ExternalWalletType, tokenAddress?: string) =>
|
|
41
|
+
this.getBalance(type, tokenAddress),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async detectWallets(): Promise<ExternalWallet[]> {
|
|
46
|
+
const wallets = Array.from(this.walletAdapters.values()).map((adapter) =>
|
|
47
|
+
adapter.getInfo(),
|
|
48
|
+
) as ExternalWallet[];
|
|
49
|
+
|
|
50
|
+
return wallets;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private getWalletAdapter(type: ExternalWalletType): WalletAdapter {
|
|
54
|
+
const adapter = this.walletAdapters.get(type);
|
|
55
|
+
if (!adapter) {
|
|
56
|
+
throw new Error(`Unsupported wallet type: ${type}`);
|
|
57
|
+
}
|
|
58
|
+
return adapter;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private handleError(
|
|
62
|
+
type: ExternalWalletType,
|
|
63
|
+
error: unknown,
|
|
64
|
+
operation: string,
|
|
65
|
+
): ExternalWalletResponse {
|
|
66
|
+
const errorMessage =
|
|
67
|
+
error instanceof Error ? error.message : "Unknown error";
|
|
68
|
+
console.error(`Error ${operation} with ${type} wallet:`, error);
|
|
69
|
+
return { success: false, wallet: type, error: errorMessage };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async connectWallet(
|
|
73
|
+
type: ExternalWalletType,
|
|
74
|
+
): Promise<ExternalWalletResponse> {
|
|
75
|
+
try {
|
|
76
|
+
if (this.connectedWallets.has(type)) {
|
|
77
|
+
const wallet = this.connectedWallets.get(type)!;
|
|
78
|
+
return { success: true, wallet: type, account: wallet.type };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const wallet = this.getWalletAdapter(type);
|
|
82
|
+
const response = await wallet.connect();
|
|
83
|
+
|
|
84
|
+
if (response.success) {
|
|
85
|
+
this.connectedWallets.set(type, wallet);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return response;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
return this.handleError(type, error, "connecting to");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async signMessage(
|
|
95
|
+
type: ExternalWalletType,
|
|
96
|
+
message: string,
|
|
97
|
+
): Promise<ExternalWalletResponse> {
|
|
98
|
+
try {
|
|
99
|
+
if (!this.connectedWallets.has(type)) {
|
|
100
|
+
throw new Error(`Wallet ${type} is not connected`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const wallet = this.connectedWallets.get(type)!;
|
|
104
|
+
if (!wallet.signMessage) {
|
|
105
|
+
throw new Error(`Wallet ${type} does not support signing messages`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return await wallet.signMessage(message);
|
|
109
|
+
} catch (error) {
|
|
110
|
+
return this.handleError(type, error, "signing message with");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async signTypedData(
|
|
115
|
+
type: ExternalWalletType,
|
|
116
|
+
data: any,
|
|
117
|
+
): Promise<ExternalWalletResponse> {
|
|
118
|
+
try {
|
|
119
|
+
if (!this.connectedWallets.has(type)) {
|
|
120
|
+
throw new Error(`Wallet ${type} is not connected`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const wallet = this.connectedWallets.get(type)!;
|
|
124
|
+
if (!wallet.signTypedData) {
|
|
125
|
+
throw new Error(`Wallet ${type} does not support signing typed data`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return await wallet.signTypedData(data);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
return this.handleError(type, error, "signing typed data with");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async getBalance(
|
|
135
|
+
type: ExternalWalletType,
|
|
136
|
+
tokenAddress?: string,
|
|
137
|
+
): Promise<ExternalWalletResponse> {
|
|
138
|
+
try {
|
|
139
|
+
if (!this.connectedWallets.has(type)) {
|
|
140
|
+
throw new Error(`Wallet ${type} is not connected`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const wallet = this.connectedWallets.get(type)!;
|
|
144
|
+
return await wallet.getBalance(tokenAddress);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
return this.handleError(type, error, "getting balance from");
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
declare global {
|
|
152
|
+
interface Window {
|
|
153
|
+
ethereum?: any;
|
|
154
|
+
solana?: any;
|
|
155
|
+
starknet_argentX?: any;
|
|
156
|
+
wallet_bridge?: WalletBridge;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export type {
|
|
161
|
+
ExternalWalletType,
|
|
162
|
+
ExternalWallet,
|
|
163
|
+
ExternalWalletResponse,
|
|
164
|
+
WalletAdapter,
|
|
165
|
+
} from "./types";
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WalletAdapter,
|
|
3
|
+
ExternalWallet,
|
|
4
|
+
ExternalWalletResponse,
|
|
5
|
+
ExternalWalletType,
|
|
6
|
+
ExternalPlatform,
|
|
7
|
+
} from "../types";
|
|
8
|
+
import { MetaMaskSDK } from "@metamask/sdk";
|
|
9
|
+
|
|
10
|
+
export class MetaMaskWallet implements WalletAdapter {
|
|
11
|
+
readonly type: ExternalWalletType = "metamask";
|
|
12
|
+
readonly platform: ExternalPlatform = "ethereum";
|
|
13
|
+
private MMSDK: MetaMaskSDK;
|
|
14
|
+
private account: string | undefined = undefined;
|
|
15
|
+
|
|
16
|
+
constructor() {
|
|
17
|
+
this.MMSDK = new MetaMaskSDK({
|
|
18
|
+
dappMetadata: {
|
|
19
|
+
name: "Cartridge Controller",
|
|
20
|
+
url: window.location.href,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
isAvailable(): boolean {
|
|
26
|
+
return typeof window !== "undefined" && !!window.ethereum?.isMetaMask;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getInfo(): ExternalWallet {
|
|
30
|
+
const available = this.isAvailable();
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
type: this.type,
|
|
34
|
+
available,
|
|
35
|
+
version: available ? window.ethereum?.version || "Unknown" : undefined,
|
|
36
|
+
chainId: available ? window.ethereum?.chainId : undefined,
|
|
37
|
+
name: "MetaMask",
|
|
38
|
+
platform: this.platform,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async connect(): Promise<ExternalWalletResponse<any>> {
|
|
43
|
+
if (this.account) {
|
|
44
|
+
return { success: true, wallet: this.type, account: this.account };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
if (!this.isAvailable()) {
|
|
49
|
+
throw new Error("MetaMask is not available");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const accounts = await this.MMSDK.connect();
|
|
53
|
+
if (accounts && accounts.length > 0) {
|
|
54
|
+
this.account = accounts[0];
|
|
55
|
+
return { success: true, wallet: this.type, account: this.account };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
throw new Error("No accounts found");
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error(`Error connecting to MetaMask:`, error);
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
wallet: this.type,
|
|
64
|
+
error: (error as Error).message || "Unknown error",
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async signTransaction(
|
|
70
|
+
transaction: any,
|
|
71
|
+
): Promise<ExternalWalletResponse<any>> {
|
|
72
|
+
try {
|
|
73
|
+
if (!this.isAvailable() || !this.account) {
|
|
74
|
+
throw new Error("MetaMask is not connected");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const ethereum = this.MMSDK.getProvider();
|
|
78
|
+
if (!ethereum) {
|
|
79
|
+
throw new Error("MetaMask is not connected");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const result = await ethereum.request({
|
|
83
|
+
method: "eth_sendTransaction",
|
|
84
|
+
params: [transaction],
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return { success: true, wallet: this.type, result };
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error(`Error signing transaction with MetaMask:`, error);
|
|
90
|
+
return {
|
|
91
|
+
success: false,
|
|
92
|
+
wallet: this.type,
|
|
93
|
+
error: (error as Error).message || "Unknown error",
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async signMessage(message: string): Promise<ExternalWalletResponse<any>> {
|
|
99
|
+
try {
|
|
100
|
+
if (!this.isAvailable() || !this.account) {
|
|
101
|
+
throw new Error("MetaMask is not connected");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const result = await this.MMSDK.connectAndSign({
|
|
105
|
+
msg: message,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return { success: true, wallet: this.type, result };
|
|
109
|
+
} catch (error) {
|
|
110
|
+
console.error(`Error signing message with MetaMask:`, error);
|
|
111
|
+
return {
|
|
112
|
+
success: false,
|
|
113
|
+
wallet: this.type,
|
|
114
|
+
error: (error as Error).message || "Unknown error",
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async signTypedData(data: any): Promise<ExternalWalletResponse<any>> {
|
|
120
|
+
try {
|
|
121
|
+
if (!this.isAvailable() || !this.account) {
|
|
122
|
+
throw new Error("MetaMask is not connected");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const ethereum = this.MMSDK.getProvider();
|
|
126
|
+
if (!ethereum) {
|
|
127
|
+
throw new Error("MetaMask is not connected");
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const result = await ethereum.request({
|
|
131
|
+
method: "eth_signTypedData_v4",
|
|
132
|
+
params: [this.account, JSON.stringify(data)],
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
return { success: true, wallet: this.type, result };
|
|
136
|
+
} catch (error) {
|
|
137
|
+
console.error(`Error signing typed data with MetaMask:`, error);
|
|
138
|
+
return {
|
|
139
|
+
success: false,
|
|
140
|
+
wallet: this.type,
|
|
141
|
+
error: (error as Error).message || "Unknown error",
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async switchChain(chainId: string): Promise<boolean> {
|
|
147
|
+
try {
|
|
148
|
+
if (!this.isAvailable()) {
|
|
149
|
+
throw new Error("MetaMask is not available");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const ethereum = this.MMSDK.getProvider();
|
|
153
|
+
if (!ethereum) {
|
|
154
|
+
throw new Error("MetaMask is not connected");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
await ethereum.request({
|
|
159
|
+
method: "wallet_switchEthereumChain",
|
|
160
|
+
params: [{ chainId }],
|
|
161
|
+
});
|
|
162
|
+
return true;
|
|
163
|
+
} catch (error) {
|
|
164
|
+
if ((error as any).code === 4902) {
|
|
165
|
+
console.warn("Chain not added to MetaMask");
|
|
166
|
+
}
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.error(`Error switching chain for MetaMask:`, error);
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async getBalance(
|
|
176
|
+
tokenAddress?: string,
|
|
177
|
+
): Promise<ExternalWalletResponse<any>> {
|
|
178
|
+
try {
|
|
179
|
+
if (!this.isAvailable() || !this.account) {
|
|
180
|
+
throw new Error("MetaMask is not connected");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (tokenAddress) {
|
|
184
|
+
return {
|
|
185
|
+
success: false,
|
|
186
|
+
wallet: this.type,
|
|
187
|
+
error: "Not implemented for ERC20",
|
|
188
|
+
};
|
|
189
|
+
} else {
|
|
190
|
+
const ethereum = this.MMSDK.getProvider();
|
|
191
|
+
if (!ethereum) {
|
|
192
|
+
throw new Error("MetaMask is not connected");
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const balance = await ethereum.request({
|
|
196
|
+
method: "eth_getBalance",
|
|
197
|
+
params: [this.account, "latest"],
|
|
198
|
+
});
|
|
199
|
+
return { success: true, wallet: this.type, result: balance };
|
|
200
|
+
}
|
|
201
|
+
} catch (error) {
|
|
202
|
+
console.error(`Error getting balance from MetaMask:`, error);
|
|
203
|
+
return {
|
|
204
|
+
success: false,
|
|
205
|
+
wallet: this.type,
|
|
206
|
+
error: (error as Error).message || "Unknown error",
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WalletAdapter,
|
|
3
|
+
ExternalWallet,
|
|
4
|
+
ExternalWalletResponse,
|
|
5
|
+
ExternalWalletType,
|
|
6
|
+
ExternalPlatform,
|
|
7
|
+
} from "../types";
|
|
8
|
+
|
|
9
|
+
export class PhantomWallet implements WalletAdapter {
|
|
10
|
+
readonly type: ExternalWalletType = "phantom";
|
|
11
|
+
readonly platform: ExternalPlatform = "solana";
|
|
12
|
+
private account: string | undefined = undefined;
|
|
13
|
+
|
|
14
|
+
isAvailable(): boolean {
|
|
15
|
+
return typeof window !== "undefined" && !!window.solana?.isPhantom;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getInfo(): ExternalWallet {
|
|
19
|
+
const available = this.isAvailable();
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
type: this.type,
|
|
23
|
+
available,
|
|
24
|
+
version: "Unknown",
|
|
25
|
+
name: "Phantom",
|
|
26
|
+
platform: this.platform,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async connect(): Promise<ExternalWalletResponse<any>> {
|
|
31
|
+
if (this.account) {
|
|
32
|
+
return { success: true, wallet: this.type, account: this.account };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
if (!this.isAvailable()) {
|
|
37
|
+
throw new Error("Phantom is not available");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const response = await window.solana.connect();
|
|
41
|
+
if (response.publicKey) {
|
|
42
|
+
this.account = response.publicKey.toString();
|
|
43
|
+
return { success: true, wallet: this.type, account: this.account };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
throw new Error("No accounts found");
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error(`Error connecting to Phantom:`, error);
|
|
49
|
+
return {
|
|
50
|
+
success: false,
|
|
51
|
+
wallet: this.type,
|
|
52
|
+
error: (error as Error).message || "Unknown error",
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async signTransaction(
|
|
58
|
+
transaction: any,
|
|
59
|
+
): Promise<ExternalWalletResponse<any>> {
|
|
60
|
+
try {
|
|
61
|
+
if (!this.isAvailable() || !this.account) {
|
|
62
|
+
throw new Error("Phantom is not connected");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const result = await window.solana.signTransaction(transaction);
|
|
66
|
+
return { success: true, wallet: this.type, result };
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.error(`Error signing transaction with Phantom:`, error);
|
|
69
|
+
return {
|
|
70
|
+
success: false,
|
|
71
|
+
wallet: this.type,
|
|
72
|
+
error: (error as Error).message || "Unknown error",
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async signMessage(message: string): Promise<ExternalWalletResponse<any>> {
|
|
78
|
+
try {
|
|
79
|
+
if (!this.isAvailable() || !this.account) {
|
|
80
|
+
throw new Error("Phantom is not connected");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const encodedMessage = new TextEncoder().encode(message);
|
|
84
|
+
const result = await window.solana.signMessage(encodedMessage, "utf8");
|
|
85
|
+
return { success: true, wallet: this.type, result };
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error(`Error signing message with Phantom:`, error);
|
|
88
|
+
return {
|
|
89
|
+
success: false,
|
|
90
|
+
wallet: this.type,
|
|
91
|
+
error: (error as Error).message || "Unknown error",
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async switchChain(_chainId: string): Promise<boolean> {
|
|
97
|
+
console.warn("Chain switching not supported for Phantom");
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async getBalance(
|
|
102
|
+
_tokenAddress?: string,
|
|
103
|
+
): Promise<ExternalWalletResponse<any>> {
|
|
104
|
+
try {
|
|
105
|
+
if (!this.isAvailable() || !this.account) {
|
|
106
|
+
throw new Error("Phantom is not connected");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// TODO: Implement balance fetching based on Phantom's API
|
|
110
|
+
return {
|
|
111
|
+
success: true,
|
|
112
|
+
wallet: this.type,
|
|
113
|
+
result: "Implement based on Phantom API",
|
|
114
|
+
};
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.error(`Error getting balance from Phantom:`, error);
|
|
117
|
+
return {
|
|
118
|
+
success: false,
|
|
119
|
+
wallet: this.type,
|
|
120
|
+
error: (error as Error).message || "Unknown error",
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type ExternalWalletType = "argent" | "metamask" | "phantom";
|
|
2
|
+
export type ExternalPlatform = "starknet" | "ethereum" | "solana";
|
|
3
|
+
|
|
4
|
+
export interface ExternalWallet {
|
|
5
|
+
type: ExternalWalletType;
|
|
6
|
+
available: boolean;
|
|
7
|
+
version?: string;
|
|
8
|
+
chainId?: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
platform?: ExternalPlatform;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ExternalWalletResponse<T = unknown> {
|
|
14
|
+
success: boolean;
|
|
15
|
+
wallet: ExternalWalletType;
|
|
16
|
+
result?: T;
|
|
17
|
+
error?: string;
|
|
18
|
+
account?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface WalletAdapter {
|
|
22
|
+
type: ExternalWalletType;
|
|
23
|
+
platform: ExternalPlatform;
|
|
24
|
+
|
|
25
|
+
// Methods
|
|
26
|
+
isAvailable(): boolean;
|
|
27
|
+
getInfo(): ExternalWallet;
|
|
28
|
+
connect(): Promise<ExternalWalletResponse<any>>;
|
|
29
|
+
signMessage?(message: string): Promise<ExternalWalletResponse<any>>;
|
|
30
|
+
signTypedData?(data: any): Promise<ExternalWalletResponse<any>>;
|
|
31
|
+
getBalance(tokenAddress?: string): Promise<ExternalWalletResponse<any>>;
|
|
32
|
+
}
|