@karn_lat/protocol-sdk 0.1.0-alpha.4 → 0.1.0-alpha.5

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.
@@ -5,31 +5,12 @@
5
5
  * https://freighter.app
6
6
  */
7
7
  import { WalletAdapter, WalletType, WalletMetadata, SignTransactionOptions } from '../types.js';
8
- interface FreighterAPI {
9
- isConnected(): Promise<boolean>;
10
- getPublicKey(): Promise<string>;
11
- signTransaction(xdr: string, opts?: {
12
- network?: string;
13
- networkPassphrase?: string;
14
- accountToSign?: string;
15
- }): Promise<string>;
16
- getNetwork(): Promise<string>;
17
- getNetworkDetails(): Promise<{
18
- network: string;
19
- networkPassphrase: string;
20
- }>;
21
- }
22
- declare global {
23
- interface Window {
24
- freighter?: FreighterAPI;
25
- }
26
- }
27
8
  export declare class FreighterAdapter implements WalletAdapter {
28
9
  type: WalletType;
29
10
  metadata: WalletMetadata;
30
- private api;
31
- constructor();
32
- private init;
11
+ private freighter;
12
+ private canUseBrowserFreighterApi;
13
+ private loadFreighter;
33
14
  isAvailable(): Promise<boolean>;
34
15
  connect(): Promise<string>;
35
16
  disconnect(): Promise<void>;
@@ -38,5 +19,4 @@ export declare class FreighterAdapter implements WalletAdapter {
38
19
  signTransaction(xdr: string, options?: SignTransactionOptions): Promise<string>;
39
20
  getNetwork(): Promise<string>;
40
21
  }
41
- export {};
42
22
  //# sourceMappingURL=FreighterAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FreighterAdapter.d.ts","sourceRoot":"","sources":["../../../src/wallet/adapters/FreighterAdapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,aAAa,EACb,UAAU,EACV,cAAc,EACd,sBAAsB,EAGvB,MAAM,aAAa,CAAC;AAGrB,UAAU,YAAY;IACpB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,eAAe,CACb,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GAC9E,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,iBAAiB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC9E;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,SAAS,CAAC,EAAE,YAAY,CAAC;KAC1B;CACF;AAED,qBAAa,gBAAiB,YAAW,aAAa;IACpD,IAAI,aAAwB;IAE5B,QAAQ,EAAE,cAAc,CAQtB;IAEF,OAAO,CAAC,GAAG,CAA6B;;IAMxC,OAAO,CAAC,IAAI;IAON,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IA8B1B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAapC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAU/B,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,MAAM,CAAC;IAiCZ,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;CAmBpC"}
1
+ {"version":3,"file":"FreighterAdapter.d.ts","sourceRoot":"","sources":["../../../src/wallet/adapters/FreighterAdapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,aAAa,EACb,UAAU,EACV,cAAc,EACd,sBAAsB,EAGvB,MAAM,aAAa,CAAC;AAarB,qBAAa,gBAAiB,YAAW,aAAa;IACpD,IAAI,aAAwB;IAE5B,QAAQ,EAAE,cAAc,CAQtB;IAEF,OAAO,CAAC,SAAS,CAAgC;IAEjD,OAAO,CAAC,yBAAyB;YAUnB,aAAa;IA0BrB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAa/B,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IA2B1B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAcpC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAU/B,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,MAAM,CAAC;IA8BZ,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;CAgBpC"}
@@ -17,24 +17,60 @@ export class FreighterAdapter {
17
17
  description: 'Official Stellar wallet extension with Soroban support',
18
18
  isAvailable: false,
19
19
  };
20
- this.api = null;
21
- this.init();
20
+ this.freighter = null;
22
21
  }
23
- init() {
24
- if (typeof window !== 'undefined' && window.freighter) {
25
- this.api = window.freighter;
26
- this.metadata.isAvailable = true;
22
+ canUseBrowserFreighterApi() {
23
+ // In Node/Jest we may have `global.window` mocked but without real browser globals.
24
+ // `@stellar/freighter-api` touches `window.location.origin` at import time.
25
+ return (typeof window !== 'undefined' &&
26
+ typeof window.location?.origin === 'string' &&
27
+ typeof document !== 'undefined');
28
+ }
29
+ async loadFreighter() {
30
+ if (this.freighter)
31
+ return this.freighter;
32
+ // 1) Prefer legacy window injection if present (also used by our Jest tests).
33
+ if (typeof window !== 'undefined') {
34
+ const injected = window.freighter;
35
+ if (injected) {
36
+ this.freighter = injected;
37
+ return injected;
38
+ }
39
+ }
40
+ // 2) In real browsers, use the official module API.
41
+ if (!this.canUseBrowserFreighterApi()) {
42
+ throw new WalletError('Freighter is not installed', WalletErrorCode.NOT_INSTALLED, WalletType.FREIGHTER);
43
+ }
44
+ try {
45
+ const mod = (await import('@stellar/freighter-api'));
46
+ this.freighter = mod;
47
+ return mod;
48
+ }
49
+ catch {
50
+ throw new WalletError('Freighter is not installed', WalletErrorCode.NOT_INSTALLED, WalletType.FREIGHTER);
27
51
  }
28
52
  }
29
53
  async isAvailable() {
30
- return this.metadata.isAvailable;
54
+ try {
55
+ const freighter = await this.loadFreighter();
56
+ if (typeof freighter.isConnected !== 'function')
57
+ return false;
58
+ await freighter.isConnected();
59
+ this.metadata.isAvailable = true;
60
+ return true;
61
+ }
62
+ catch {
63
+ this.metadata.isAvailable = false;
64
+ return false;
65
+ }
31
66
  }
32
67
  async connect() {
33
- if (!this.api) {
34
- throw new WalletError('Freighter is not installed. Please install from https://freighter.app', WalletErrorCode.NOT_INSTALLED, WalletType.FREIGHTER);
68
+ const freighter = await this.loadFreighter();
69
+ if (typeof freighter.getPublicKey !== 'function') {
70
+ throw new WalletError('Freighter API is unavailable', WalletErrorCode.NOT_INSTALLED, WalletType.FREIGHTER);
35
71
  }
36
72
  try {
37
- const publicKey = await this.api.getPublicKey();
73
+ const publicKey = await freighter.getPublicKey();
38
74
  if (!publicKey) {
39
75
  throw new WalletError('User rejected connection request', WalletErrorCode.USER_REJECTED, WalletType.FREIGHTER);
40
76
  }
@@ -49,37 +85,41 @@ export class FreighterAdapter {
49
85
  async disconnect() {
50
86
  // Freighter doesn't have explicit disconnect
51
87
  // Connection state is managed by extension
52
- this.api = null;
88
+ // Keep module cached, just mark unavailable until next check.
89
+ this.metadata.isAvailable = false;
53
90
  }
54
91
  async getAddress() {
55
- if (!this.api)
56
- return null;
57
92
  try {
58
- const connected = await this.api.isConnected();
93
+ const freighter = await this.loadFreighter();
94
+ if (typeof freighter.isConnected !== 'function' || typeof freighter.getPublicKey !== 'function')
95
+ return null;
96
+ const connected = await freighter.isConnected();
59
97
  if (!connected)
60
98
  return null;
61
- return await this.api.getPublicKey();
99
+ return await freighter.getPublicKey();
62
100
  }
63
101
  catch {
64
102
  return null;
65
103
  }
66
104
  }
67
105
  async isConnected() {
68
- if (!this.api)
69
- return false;
70
106
  try {
71
- return await this.api.isConnected();
107
+ const freighter = await this.loadFreighter();
108
+ if (typeof freighter.isConnected !== 'function')
109
+ return false;
110
+ return await freighter.isConnected();
72
111
  }
73
112
  catch {
74
113
  return false;
75
114
  }
76
115
  }
77
116
  async signTransaction(xdr, options) {
78
- if (!this.api) {
117
+ const freighter = await this.loadFreighter();
118
+ if (typeof freighter.signTransaction !== 'function') {
79
119
  throw new WalletError('Freighter is not connected', WalletErrorCode.NOT_CONNECTED, WalletType.FREIGHTER);
80
120
  }
81
121
  try {
82
- const signedXdr = await this.api.signTransaction(xdr, {
122
+ const signedXdr = await freighter.signTransaction(xdr, {
83
123
  networkPassphrase: options?.networkPassphrase,
84
124
  accountToSign: options?.accountToSign,
85
125
  });
@@ -93,11 +133,12 @@ export class FreighterAdapter {
93
133
  }
94
134
  }
95
135
  async getNetwork() {
96
- if (!this.api) {
136
+ const freighter = await this.loadFreighter();
137
+ if (typeof freighter.getNetwork !== 'function') {
97
138
  throw new WalletError('Freighter is not connected', WalletErrorCode.NOT_CONNECTED, WalletType.FREIGHTER);
98
139
  }
99
140
  try {
100
- return await this.api.getNetwork();
141
+ return await freighter.getNetwork();
101
142
  }
102
143
  catch (error) {
103
144
  throw new WalletError(`Failed to get network: ${error.message}`, WalletErrorCode.NETWORK_ERROR, WalletType.FREIGHTER);
@@ -1 +1 @@
1
- {"version":3,"file":"FreighterAdapter.js","sourceRoot":"","sources":["../../../src/wallet/adapters/FreighterAdapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FreighterAdapter.js","sourceRoot":"","sources":["../../../src/wallet/adapters/FreighterAdapter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@karn_lat/protocol-sdk",
3
- "version": "0.1.0-alpha.4",
3
+ "version": "0.1.0-alpha.5",
4
4
  "description": "Official TypeScript SDK for Karn Protocol - Contribution-driven governance on Stellar",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -71,5 +71,5 @@
71
71
  "bugs": {
72
72
  "url": "https://github.com/ThaisFReis/karn-protocol/issues"
73
73
  },
74
- "homepage": "https://github.com/ThaisFReis/karn-protocol#readme"
74
+ "homepage": "https://karn-protocol.vercel.app/"
75
75
  }
@@ -14,23 +14,16 @@ import {
14
14
  WalletErrorCode,
15
15
  } from '../types.js';
16
16
 
17
- // Freighter API types (from @stellar/freighter-api)
18
- interface FreighterAPI {
19
- isConnected(): Promise<boolean>;
20
- getPublicKey(): Promise<string>;
21
- signTransaction(
17
+ type FreighterModule = {
18
+ isConnected?: () => Promise<boolean>;
19
+ getPublicKey?: () => Promise<string>;
20
+ signTransaction?: (
22
21
  xdr: string,
23
22
  opts?: { network?: string; networkPassphrase?: string; accountToSign?: string }
24
- ): Promise<string>;
25
- getNetwork(): Promise<string>;
26
- getNetworkDetails(): Promise<{ network: string; networkPassphrase: string }>;
27
- }
28
-
29
- declare global {
30
- interface Window {
31
- freighter?: FreighterAPI;
32
- }
33
- }
23
+ ) => Promise<string>;
24
+ getNetwork?: () => Promise<string>;
25
+ getNetworkDetails?: () => Promise<{ network: string; networkPassphrase: string }>;
26
+ };
34
27
 
35
28
  export class FreighterAdapter implements WalletAdapter {
36
29
  type = WalletType.FREIGHTER;
@@ -45,34 +38,65 @@ export class FreighterAdapter implements WalletAdapter {
45
38
  isAvailable: false,
46
39
  };
47
40
 
48
- private api: FreighterAPI | null = null;
41
+ private freighter: FreighterModule | null = null;
49
42
 
50
- constructor() {
51
- this.init();
43
+ private canUseBrowserFreighterApi(): boolean {
44
+ // In Node/Jest we may have `global.window` mocked but without real browser globals.
45
+ // `@stellar/freighter-api` touches `window.location.origin` at import time.
46
+ return (
47
+ typeof window !== 'undefined' &&
48
+ typeof (window as any).location?.origin === 'string' &&
49
+ typeof document !== 'undefined'
50
+ );
52
51
  }
53
52
 
54
- private init() {
55
- if (typeof window !== 'undefined' && window.freighter) {
56
- this.api = window.freighter;
57
- this.metadata.isAvailable = true;
53
+ private async loadFreighter(): Promise<FreighterModule> {
54
+ if (this.freighter) return this.freighter;
55
+
56
+ // 1) Prefer legacy window injection if present (also used by our Jest tests).
57
+ if (typeof window !== 'undefined') {
58
+ const injected = (window as any).freighter as FreighterModule | undefined;
59
+ if (injected) {
60
+ this.freighter = injected;
61
+ return injected;
62
+ }
63
+ }
64
+
65
+ // 2) In real browsers, use the official module API.
66
+ if (!this.canUseBrowserFreighterApi()) {
67
+ throw new WalletError('Freighter is not installed', WalletErrorCode.NOT_INSTALLED, WalletType.FREIGHTER);
68
+ }
69
+
70
+ try {
71
+ const mod = (await import('@stellar/freighter-api')) as unknown as FreighterModule;
72
+ this.freighter = mod;
73
+ return mod;
74
+ } catch {
75
+ throw new WalletError('Freighter is not installed', WalletErrorCode.NOT_INSTALLED, WalletType.FREIGHTER);
58
76
  }
59
77
  }
60
78
 
61
79
  async isAvailable(): Promise<boolean> {
62
- return this.metadata.isAvailable;
80
+ try {
81
+ const freighter = await this.loadFreighter();
82
+ if (typeof freighter.isConnected !== 'function') return false;
83
+ await freighter.isConnected();
84
+ this.metadata.isAvailable = true;
85
+ return true;
86
+ } catch {
87
+ this.metadata.isAvailable = false;
88
+ return false;
89
+ }
63
90
  }
64
91
 
65
92
  async connect(): Promise<string> {
66
- if (!this.api) {
67
- throw new WalletError(
68
- 'Freighter is not installed. Please install from https://freighter.app',
69
- WalletErrorCode.NOT_INSTALLED,
70
- WalletType.FREIGHTER
71
- );
93
+ const freighter = await this.loadFreighter();
94
+ if (typeof freighter.getPublicKey !== 'function') {
95
+ throw new WalletError('Freighter API is unavailable', WalletErrorCode.NOT_INSTALLED, WalletType.FREIGHTER);
72
96
  }
73
97
 
74
98
  try {
75
- const publicKey = await this.api.getPublicKey();
99
+ const publicKey = await freighter.getPublicKey();
76
100
  if (!publicKey) {
77
101
  throw new WalletError(
78
102
  'User rejected connection request',
@@ -95,27 +119,29 @@ export class FreighterAdapter implements WalletAdapter {
95
119
  async disconnect(): Promise<void> {
96
120
  // Freighter doesn't have explicit disconnect
97
121
  // Connection state is managed by extension
98
- this.api = null;
122
+ // Keep module cached, just mark unavailable until next check.
123
+ this.metadata.isAvailable = false;
99
124
  }
100
125
 
101
126
  async getAddress(): Promise<string | null> {
102
- if (!this.api) return null;
103
-
104
127
  try {
105
- const connected = await this.api.isConnected();
128
+ const freighter = await this.loadFreighter();
129
+ if (typeof freighter.isConnected !== 'function' || typeof freighter.getPublicKey !== 'function') return null;
130
+
131
+ const connected = await freighter.isConnected();
106
132
  if (!connected) return null;
107
133
 
108
- return await this.api.getPublicKey();
134
+ return await freighter.getPublicKey();
109
135
  } catch {
110
136
  return null;
111
137
  }
112
138
  }
113
139
 
114
140
  async isConnected(): Promise<boolean> {
115
- if (!this.api) return false;
116
-
117
141
  try {
118
- return await this.api.isConnected();
142
+ const freighter = await this.loadFreighter();
143
+ if (typeof freighter.isConnected !== 'function') return false;
144
+ return await freighter.isConnected();
119
145
  } catch {
120
146
  return false;
121
147
  }
@@ -125,16 +151,13 @@ export class FreighterAdapter implements WalletAdapter {
125
151
  xdr: string,
126
152
  options?: SignTransactionOptions
127
153
  ): Promise<string> {
128
- if (!this.api) {
129
- throw new WalletError(
130
- 'Freighter is not connected',
131
- WalletErrorCode.NOT_CONNECTED,
132
- WalletType.FREIGHTER
133
- );
154
+ const freighter = await this.loadFreighter();
155
+ if (typeof freighter.signTransaction !== 'function') {
156
+ throw new WalletError('Freighter is not connected', WalletErrorCode.NOT_CONNECTED, WalletType.FREIGHTER);
134
157
  }
135
158
 
136
159
  try {
137
- const signedXdr = await this.api.signTransaction(xdr, {
160
+ const signedXdr = await freighter.signTransaction(xdr, {
138
161
  networkPassphrase: options?.networkPassphrase,
139
162
  accountToSign: options?.accountToSign,
140
163
  });
@@ -158,16 +181,13 @@ export class FreighterAdapter implements WalletAdapter {
158
181
  }
159
182
 
160
183
  async getNetwork(): Promise<string> {
161
- if (!this.api) {
162
- throw new WalletError(
163
- 'Freighter is not connected',
164
- WalletErrorCode.NOT_CONNECTED,
165
- WalletType.FREIGHTER
166
- );
184
+ const freighter = await this.loadFreighter();
185
+ if (typeof freighter.getNetwork !== 'function') {
186
+ throw new WalletError('Freighter is not connected', WalletErrorCode.NOT_CONNECTED, WalletType.FREIGHTER);
167
187
  }
168
188
 
169
189
  try {
170
- return await this.api.getNetwork();
190
+ return await freighter.getNetwork();
171
191
  } catch (error: any) {
172
192
  throw new WalletError(
173
193
  `Failed to get network: ${error.message}`,