@cartridge/controller 0.6.0 → 0.7.1
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 +52 -76
- package/.turbo/turbo-build.log +53 -77
- package/dist/controller.cjs +860 -0
- package/dist/controller.cjs.map +1 -0
- package/dist/controller.d.cts +33 -0
- package/dist/controller.d.ts +4 -4
- package/dist/controller.js +84 -68
- package/dist/controller.js.map +1 -1
- package/dist/index.cjs +2200 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +17 -0
- package/dist/index.d.ts +12 -7
- package/dist/index.js +161 -7601
- package/dist/index.js.map +1 -1
- package/dist/lookup.cjs +59 -0
- package/dist/lookup.cjs.map +1 -0
- package/dist/lookup.d.cts +4 -0
- package/dist/lookup.js +7 -7
- package/dist/lookup.js.map +1 -1
- package/dist/{provider.js → node/index.cjs} +499 -25
- package/dist/node/index.cjs.map +1 -0
- package/dist/node/index.d.cts +56 -0
- package/dist/node/index.d.ts +56 -0
- package/dist/{telegram/provider.js → node/index.js} +354 -135
- package/dist/node/index.js.map +1 -0
- package/dist/{policies.d.ts → policies-DD1aPjQ4.d.cts} +6 -4
- package/dist/policies-DD1aPjQ4.d.ts +21 -0
- package/dist/{types-CVnDQVqD.d.ts → provider-ap1C1ypF.d.cts} +27 -10
- package/dist/provider-ap1C1ypF.d.ts +201 -0
- package/dist/session/{provider.js → index.cjs} +82 -73
- package/dist/session/index.cjs.map +1 -0
- package/dist/session/{provider.d.ts → index.d.cts} +6 -3
- package/dist/session/index.d.ts +37 -8
- package/dist/session/index.js +47 -64
- package/dist/session/index.js.map +1 -1
- package/package.json +35 -16
- package/src/controller.ts +43 -15
- package/src/iframe/base.ts +1 -11
- package/src/node/account.ts +72 -0
- package/src/node/backend.ts +159 -0
- package/src/node/index.ts +4 -0
- package/src/node/provider.ts +178 -0
- package/src/node/server.ts +89 -0
- package/src/session/account.ts +1 -1
- package/src/session/provider.ts +0 -16
- package/src/types.ts +3 -6
- package/tsconfig.json +2 -1
- package/dist/__tests__/parseChainId.test.d.ts +0 -2
- package/dist/__tests__/parseChainId.test.js +0 -89
- package/dist/__tests__/parseChainId.test.js.map +0 -1
- package/dist/account.d.ts +0 -38
- package/dist/account.js +0 -110
- package/dist/account.js.map +0 -1
- package/dist/constants.d.ts +0 -5
- package/dist/constants.js +0 -10
- package/dist/constants.js.map +0 -1
- package/dist/errors.d.ts +0 -5
- package/dist/errors.js +0 -11
- package/dist/errors.js.map +0 -1
- package/dist/icon.d.ts +0 -3
- package/dist/icon.js +0 -6
- package/dist/icon.js.map +0 -1
- package/dist/iframe/base.d.ts +0 -5
- package/dist/iframe/base.js +0 -126
- package/dist/iframe/base.js.map +0 -1
- package/dist/iframe/index.d.ts +0 -5
- package/dist/iframe/index.js +0 -188
- package/dist/iframe/index.js.map +0 -1
- package/dist/iframe/keychain.d.ts +0 -5
- package/dist/iframe/keychain.js +0 -147
- package/dist/iframe/keychain.js.map +0 -1
- package/dist/iframe/profile.d.ts +0 -5
- package/dist/iframe/profile.js +0 -167
- package/dist/iframe/profile.js.map +0 -1
- package/dist/index.d-BbTUPBeO.d.ts +0 -68
- package/dist/mutex.d.ts +0 -14
- package/dist/mutex.js +0 -22
- package/dist/mutex.js.map +0 -1
- package/dist/policies.js +0 -26
- package/dist/policies.js.map +0 -1
- package/dist/provider.d.ts +0 -24
- package/dist/provider.js.map +0 -1
- package/dist/session/account.d.ts +0 -37
- package/dist/session/account.js +0 -94
- package/dist/session/account.js.map +0 -1
- package/dist/session/backend.d.ts +0 -60
- package/dist/session/backend.js +0 -39
- package/dist/session/backend.js.map +0 -1
- package/dist/session/provider.js.map +0 -1
- package/dist/telegram/backend.d.ts +0 -33
- package/dist/telegram/backend.js +0 -40
- package/dist/telegram/backend.js.map +0 -1
- package/dist/telegram/provider.d.ts +0 -27
- package/dist/telegram/provider.js.map +0 -1
- package/dist/types.d.ts +0 -5
- package/dist/types.js +0 -13
- package/dist/types.js.map +0 -1
- package/dist/utils.d.ts +0 -19
- package/dist/utils.js +0 -141
- package/dist/utils.js.map +0 -1
|
@@ -1,18 +1,158 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var starknet = require('starknet');
|
|
6
|
+
var session = require('@cartridge/account-wasm/session');
|
|
7
|
+
var typesJs = require('@starknet-io/types-js');
|
|
8
|
+
var fs = require('fs/promises');
|
|
9
|
+
var path = require('path');
|
|
10
|
+
var http = require('http');
|
|
11
|
+
|
|
12
|
+
function _interopNamespace(e) {
|
|
13
|
+
if (e && e.__esModule) return e;
|
|
14
|
+
var n = Object.create(null);
|
|
15
|
+
if (e) {
|
|
16
|
+
Object.keys(e).forEach(function (k) {
|
|
17
|
+
if (k !== 'default') {
|
|
18
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
19
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return e[k]; }
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
n.default = e;
|
|
27
|
+
return Object.freeze(n);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
31
|
+
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
32
|
+
var http__namespace = /*#__PURE__*/_interopNamespace(http);
|
|
33
|
+
|
|
34
|
+
// src/node/provider.ts
|
|
35
|
+
function normalizeCalls(calls) {
|
|
36
|
+
return toArray(calls).map((call) => {
|
|
37
|
+
return {
|
|
38
|
+
entrypoint: call.entrypoint,
|
|
39
|
+
contractAddress: starknet.addAddressPadding(call.contractAddress),
|
|
40
|
+
calldata: starknet.CallData.toHex(call.calldata)
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function toWasmPolicies(policies) {
|
|
45
|
+
return [
|
|
46
|
+
...Object.entries(policies.contracts ?? {}).flatMap(
|
|
47
|
+
([target, { methods }]) => toArray(methods).map((m) => ({
|
|
48
|
+
target,
|
|
49
|
+
method: m.entrypoint,
|
|
50
|
+
authorized: m.authorized
|
|
51
|
+
}))
|
|
52
|
+
),
|
|
53
|
+
...(policies.messages ?? []).map((p) => {
|
|
54
|
+
const domainHash = starknet.typedData.getStructHash(
|
|
55
|
+
p.types,
|
|
56
|
+
"StarknetDomain",
|
|
57
|
+
p.domain,
|
|
58
|
+
starknet.TypedDataRevision.ACTIVE
|
|
59
|
+
);
|
|
60
|
+
const typeHash = starknet.typedData.getTypeHash(
|
|
61
|
+
p.types,
|
|
62
|
+
p.primaryType,
|
|
63
|
+
starknet.TypedDataRevision.ACTIVE
|
|
64
|
+
);
|
|
65
|
+
return {
|
|
66
|
+
scope_hash: starknet.hash.computePoseidonHash(domainHash, typeHash),
|
|
67
|
+
authorized: p.authorized
|
|
68
|
+
};
|
|
69
|
+
})
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
function toArray(val) {
|
|
73
|
+
return Array.isArray(val) ? val : [val];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// src/errors.ts
|
|
77
|
+
var NotReadyToConnect = class _NotReadyToConnect extends Error {
|
|
78
|
+
constructor() {
|
|
79
|
+
super("Not ready to connect");
|
|
80
|
+
Object.setPrototypeOf(this, _NotReadyToConnect.prototype);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// src/types.ts
|
|
85
|
+
var ResponseCodes = /* @__PURE__ */ ((ResponseCodes2) => {
|
|
86
|
+
ResponseCodes2["SUCCESS"] = "SUCCESS";
|
|
87
|
+
ResponseCodes2["NOT_CONNECTED"] = "NOT_CONNECTED";
|
|
88
|
+
ResponseCodes2["ERROR"] = "ERROR";
|
|
89
|
+
ResponseCodes2["CANCELED"] = "CANCELED";
|
|
90
|
+
ResponseCodes2["USER_INTERACTION_REQUIRED"] = "USER_INTERACTION_REQUIRED";
|
|
91
|
+
return ResponseCodes2;
|
|
92
|
+
})(ResponseCodes || {});
|
|
93
|
+
|
|
94
|
+
// src/node/account.ts
|
|
95
|
+
var SessionAccount = class extends starknet.WalletAccount {
|
|
96
|
+
controller;
|
|
97
|
+
constructor(provider, {
|
|
98
|
+
rpcUrl,
|
|
99
|
+
privateKey,
|
|
100
|
+
address,
|
|
101
|
+
ownerGuid,
|
|
102
|
+
chainId,
|
|
103
|
+
expiresAt,
|
|
104
|
+
policies
|
|
105
|
+
}) {
|
|
106
|
+
super({ nodeUrl: rpcUrl }, provider);
|
|
107
|
+
this.address = address;
|
|
108
|
+
this.controller = session.CartridgeSessionAccount.newAsRegistered(
|
|
109
|
+
rpcUrl,
|
|
110
|
+
privateKey,
|
|
111
|
+
address,
|
|
112
|
+
ownerGuid,
|
|
113
|
+
chainId,
|
|
114
|
+
{
|
|
115
|
+
expiresAt,
|
|
116
|
+
policies
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Invoke execute function in account contract
|
|
122
|
+
*
|
|
123
|
+
* @param calls the invocation object or an array of them, containing:
|
|
124
|
+
* - contractAddress - the address of the contract
|
|
125
|
+
* - entrypoint - the entrypoint of the contract
|
|
126
|
+
* - calldata - (defaults to []) the calldata
|
|
127
|
+
* - signature - (defaults to []) the signature
|
|
128
|
+
*
|
|
129
|
+
* @returns response from addTransaction
|
|
130
|
+
*/
|
|
131
|
+
async execute(calls) {
|
|
132
|
+
try {
|
|
133
|
+
const res = await this.controller.executeFromOutside(
|
|
134
|
+
normalizeCalls(calls)
|
|
135
|
+
);
|
|
136
|
+
return res;
|
|
137
|
+
} catch (e) {
|
|
138
|
+
return this.controller.execute(normalizeCalls(calls));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// src/constants.ts
|
|
144
|
+
var KEYCHAIN_URL = "https://x.cartridge.gg";
|
|
5
145
|
|
|
6
146
|
// package.json
|
|
7
147
|
var package_default = {
|
|
8
148
|
name: "@cartridge/controller",
|
|
9
|
-
version: "0.
|
|
149
|
+
version: "0.7.1",
|
|
10
150
|
description: "Cartridge Controller",
|
|
11
151
|
module: "dist/index.js",
|
|
12
152
|
types: "dist/index.d.ts",
|
|
13
153
|
type: "module",
|
|
14
154
|
scripts: {
|
|
15
|
-
"build:deps": "tsup
|
|
155
|
+
"build:deps": "tsup",
|
|
16
156
|
build: "pnpm build:deps",
|
|
17
157
|
format: 'prettier --write "src/**/*.ts"',
|
|
18
158
|
"format:check": 'prettier --check "src/**/*.ts"',
|
|
@@ -22,52 +162,71 @@ var package_default = {
|
|
|
22
162
|
exports: {
|
|
23
163
|
".": {
|
|
24
164
|
types: "./dist/index.d.ts",
|
|
25
|
-
|
|
165
|
+
import: "./dist/index.js",
|
|
166
|
+
require: "./dist/index.cjs"
|
|
26
167
|
},
|
|
27
168
|
"./session": {
|
|
28
169
|
types: "./dist/session/index.d.ts",
|
|
29
|
-
|
|
170
|
+
import: "./dist/session/index.js",
|
|
171
|
+
require: "./dist/session/index.cjs"
|
|
172
|
+
},
|
|
173
|
+
"./session/node": {
|
|
174
|
+
types: "./dist/node/index.d.ts",
|
|
175
|
+
import: "./dist/node/index.js",
|
|
176
|
+
require: "./dist/node/index.cjs"
|
|
30
177
|
},
|
|
31
178
|
"./provider": {
|
|
32
179
|
types: "./dist/provider/index.d.ts",
|
|
33
|
-
|
|
180
|
+
import: "./dist/provider/index.js"
|
|
34
181
|
},
|
|
35
182
|
"./types": {
|
|
36
183
|
types: "./dist/types/index.d.ts",
|
|
37
|
-
|
|
184
|
+
import: "./dist/types/index.js"
|
|
38
185
|
}
|
|
39
186
|
},
|
|
40
187
|
tsup: {
|
|
41
188
|
entry: [
|
|
42
|
-
"src
|
|
189
|
+
"src/index.ts",
|
|
190
|
+
"src/controller.ts",
|
|
191
|
+
"src/lookup.ts",
|
|
192
|
+
"src/session/index.ts",
|
|
193
|
+
"src/node/index.ts"
|
|
43
194
|
],
|
|
44
195
|
format: [
|
|
45
|
-
"esm"
|
|
196
|
+
"esm",
|
|
197
|
+
"cjs"
|
|
46
198
|
],
|
|
47
199
|
splitting: false,
|
|
48
200
|
sourcemap: true,
|
|
49
|
-
clean: true
|
|
201
|
+
clean: true,
|
|
202
|
+
dts: true,
|
|
203
|
+
treeshake: {
|
|
204
|
+
preset: "recommended"
|
|
205
|
+
},
|
|
206
|
+
exports: "named"
|
|
50
207
|
},
|
|
51
208
|
peerDependencies: {
|
|
52
|
-
starknet: "
|
|
209
|
+
starknet: "catalog:",
|
|
210
|
+
open: "^10.1.0"
|
|
53
211
|
},
|
|
54
212
|
dependencies: {
|
|
55
213
|
"@cartridge/account-wasm": "workspace:*",
|
|
56
|
-
"@cartridge/penpal": "
|
|
57
|
-
"@starknet-io/types-js": "
|
|
214
|
+
"@cartridge/penpal": "catalog:",
|
|
215
|
+
"@starknet-io/types-js": "catalog:",
|
|
58
216
|
"@telegram-apps/sdk": "^2.4.0",
|
|
59
|
-
base64url: "
|
|
217
|
+
base64url: "catalog:",
|
|
60
218
|
"cbor-x": "^1.5.0",
|
|
61
|
-
"fast-deep-equal": "
|
|
62
|
-
"query-string": "^7.1.1"
|
|
219
|
+
"fast-deep-equal": "catalog:"
|
|
63
220
|
},
|
|
64
221
|
devDependencies: {
|
|
65
222
|
"@cartridge/tsconfig": "workspace:*",
|
|
66
223
|
"@types/jest": "^29.5.14",
|
|
67
|
-
"@types/node": "
|
|
224
|
+
"@types/node": "catalog:",
|
|
68
225
|
jest: "^29.7.0",
|
|
226
|
+
prettier: "catalog:",
|
|
69
227
|
"ts-jest": "^29.2.5",
|
|
70
|
-
|
|
228
|
+
tsup: "catalog:",
|
|
229
|
+
typescript: "catalog:"
|
|
71
230
|
}
|
|
72
231
|
};
|
|
73
232
|
|
|
@@ -128,7 +287,7 @@ var BaseProvider = class {
|
|
|
128
287
|
case "wallet_getPermissions":
|
|
129
288
|
await this.safeProbe();
|
|
130
289
|
if (this.account) {
|
|
131
|
-
return [Permission.ACCOUNTS];
|
|
290
|
+
return [typesJs.Permission.ACCOUNTS];
|
|
132
291
|
}
|
|
133
292
|
return [];
|
|
134
293
|
case "wallet_requestAccounts": {
|
|
@@ -246,7 +405,322 @@ var BaseProvider = class {
|
|
|
246
405
|
});
|
|
247
406
|
}
|
|
248
407
|
};
|
|
249
|
-
|
|
250
|
-
|
|
408
|
+
var CallbackServer = class {
|
|
409
|
+
server;
|
|
410
|
+
resolveCallback;
|
|
411
|
+
rejectCallback;
|
|
412
|
+
timeoutId;
|
|
413
|
+
constructor() {
|
|
414
|
+
this.server = http__namespace.createServer(this.handleRequest.bind(this));
|
|
415
|
+
this.server.on("error", (error) => {
|
|
416
|
+
console.error("Server error:", error);
|
|
417
|
+
if (this.rejectCallback) {
|
|
418
|
+
this.rejectCallback(error);
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
cleanup() {
|
|
423
|
+
if (this.timeoutId) {
|
|
424
|
+
clearTimeout(this.timeoutId);
|
|
425
|
+
}
|
|
426
|
+
this.server.close();
|
|
427
|
+
}
|
|
428
|
+
handleRequest(req, res) {
|
|
429
|
+
if (!req.url?.startsWith("/callback")) {
|
|
430
|
+
res.writeHead(404);
|
|
431
|
+
res.end();
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
const params = new URLSearchParams(req.url.split("?")[1]);
|
|
435
|
+
const session = params.get("startapp");
|
|
436
|
+
if (!session) {
|
|
437
|
+
console.warn("Received callback without session data");
|
|
438
|
+
res.writeHead(400);
|
|
439
|
+
res.end("Missing session data");
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (this.resolveCallback) {
|
|
443
|
+
this.resolveCallback(session);
|
|
444
|
+
}
|
|
445
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
446
|
+
res.end(
|
|
447
|
+
"<html><body><script>window.close();</script>Session registered successfully. You can close this window.</body></html>"
|
|
448
|
+
);
|
|
449
|
+
this.cleanup();
|
|
450
|
+
}
|
|
451
|
+
async listen() {
|
|
452
|
+
return new Promise((resolve, reject) => {
|
|
453
|
+
this.server.listen(0, "localhost", () => {
|
|
454
|
+
const address = this.server.address();
|
|
455
|
+
const url = `http://localhost:${address.port}/callback`;
|
|
456
|
+
resolve(url);
|
|
457
|
+
});
|
|
458
|
+
this.server.on("error", reject);
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
async waitForCallback() {
|
|
462
|
+
return new Promise((resolve, reject) => {
|
|
463
|
+
this.resolveCallback = resolve;
|
|
464
|
+
this.rejectCallback = reject;
|
|
465
|
+
this.timeoutId = setTimeout(
|
|
466
|
+
() => {
|
|
467
|
+
console.warn("Callback timeout reached");
|
|
468
|
+
reject(new Error("Callback timeout after 5 minutes"));
|
|
469
|
+
this.cleanup();
|
|
470
|
+
},
|
|
471
|
+
5 * 60 * 1e3
|
|
472
|
+
);
|
|
473
|
+
});
|
|
474
|
+
}
|
|
251
475
|
};
|
|
252
|
-
|
|
476
|
+
|
|
477
|
+
// src/node/backend.ts
|
|
478
|
+
var NodeBackend = class {
|
|
479
|
+
basePath;
|
|
480
|
+
sessionFile;
|
|
481
|
+
data = {};
|
|
482
|
+
callbackServer;
|
|
483
|
+
constructor(basePath) {
|
|
484
|
+
if (!basePath) {
|
|
485
|
+
throw new Error("basePath is required for NodeBackend");
|
|
486
|
+
}
|
|
487
|
+
this.basePath = basePath;
|
|
488
|
+
this.sessionFile = path__namespace.join(this.basePath, "session.json");
|
|
489
|
+
}
|
|
490
|
+
async ensureDirectoryExists() {
|
|
491
|
+
try {
|
|
492
|
+
await fs__namespace.access(this.basePath);
|
|
493
|
+
} catch {
|
|
494
|
+
try {
|
|
495
|
+
await fs__namespace.mkdir(this.basePath, { recursive: true });
|
|
496
|
+
} catch (error) {
|
|
497
|
+
throw new Error(
|
|
498
|
+
`Failed to create directory ${this.basePath}: ${error.message}`
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
async loadData() {
|
|
504
|
+
try {
|
|
505
|
+
const content = await fs__namespace.readFile(this.sessionFile, "utf-8");
|
|
506
|
+
const parsed = JSON.parse(content);
|
|
507
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
508
|
+
throw new Error("Invalid session data format");
|
|
509
|
+
}
|
|
510
|
+
this.data = parsed;
|
|
511
|
+
} catch (error) {
|
|
512
|
+
if (error instanceof Error) {
|
|
513
|
+
if (error.code !== "ENOENT") {
|
|
514
|
+
throw new Error(`Failed to load session data: ${error.message}`);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
this.data = {};
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
async saveData() {
|
|
521
|
+
try {
|
|
522
|
+
await this.ensureDirectoryExists();
|
|
523
|
+
await fs__namespace.writeFile(
|
|
524
|
+
this.sessionFile,
|
|
525
|
+
JSON.stringify(this.data, null, 2),
|
|
526
|
+
"utf-8"
|
|
527
|
+
);
|
|
528
|
+
} catch (error) {
|
|
529
|
+
if (error instanceof Error) {
|
|
530
|
+
throw new Error(`Failed to save session data: ${error.message}`);
|
|
531
|
+
}
|
|
532
|
+
throw error;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
async get(key) {
|
|
536
|
+
if (!key) {
|
|
537
|
+
throw new Error("Key is required");
|
|
538
|
+
}
|
|
539
|
+
await this.loadData();
|
|
540
|
+
return this.data[key] ? JSON.stringify(this.data[key]) : null;
|
|
541
|
+
}
|
|
542
|
+
async set(key, value) {
|
|
543
|
+
if (!key) {
|
|
544
|
+
throw new Error("Key is required");
|
|
545
|
+
}
|
|
546
|
+
if (!value) {
|
|
547
|
+
throw new Error("Value is required");
|
|
548
|
+
}
|
|
549
|
+
await this.loadData();
|
|
550
|
+
try {
|
|
551
|
+
this.data[key] = JSON.parse(value);
|
|
552
|
+
await this.saveData();
|
|
553
|
+
} catch (error) {
|
|
554
|
+
if (error instanceof Error) {
|
|
555
|
+
throw new Error(`Failed to set ${key}: ${error.message}`);
|
|
556
|
+
}
|
|
557
|
+
throw error;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
async delete(key) {
|
|
561
|
+
if (!key) {
|
|
562
|
+
throw new Error("Key is required");
|
|
563
|
+
}
|
|
564
|
+
await this.loadData();
|
|
565
|
+
delete this.data[key];
|
|
566
|
+
await this.saveData();
|
|
567
|
+
}
|
|
568
|
+
async getRedirectUri() {
|
|
569
|
+
try {
|
|
570
|
+
this.callbackServer = new CallbackServer();
|
|
571
|
+
return await this.callbackServer.listen();
|
|
572
|
+
} catch (error) {
|
|
573
|
+
if (error instanceof Error) {
|
|
574
|
+
throw new Error(`Failed to start callback server: ${error.message}`);
|
|
575
|
+
}
|
|
576
|
+
throw error;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
async waitForCallback() {
|
|
580
|
+
if (!this.callbackServer) {
|
|
581
|
+
throw new Error("Callback server not initialized");
|
|
582
|
+
}
|
|
583
|
+
return await this.callbackServer.waitForCallback();
|
|
584
|
+
}
|
|
585
|
+
openLink(url) {
|
|
586
|
+
if (!url) {
|
|
587
|
+
throw new Error("URL is required");
|
|
588
|
+
}
|
|
589
|
+
console.log(`
|
|
590
|
+
Open url to authorize session: ${url}`);
|
|
591
|
+
}
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
// src/node/provider.ts
|
|
595
|
+
var SessionProvider = class extends BaseProvider {
|
|
596
|
+
id = "controller_session";
|
|
597
|
+
name = "Controller Session";
|
|
598
|
+
_chainId;
|
|
599
|
+
_rpcUrl;
|
|
600
|
+
_username;
|
|
601
|
+
_policies;
|
|
602
|
+
_keychainUrl;
|
|
603
|
+
_backend;
|
|
604
|
+
constructor({
|
|
605
|
+
rpc,
|
|
606
|
+
chainId,
|
|
607
|
+
policies,
|
|
608
|
+
basePath,
|
|
609
|
+
keychainUrl
|
|
610
|
+
}) {
|
|
611
|
+
super();
|
|
612
|
+
this._policies = {
|
|
613
|
+
verified: false,
|
|
614
|
+
contracts: policies.contracts ? Object.fromEntries(
|
|
615
|
+
Object.entries(policies.contracts).map(([address, contract]) => [
|
|
616
|
+
address,
|
|
617
|
+
{
|
|
618
|
+
...contract,
|
|
619
|
+
methods: contract.methods.map((method) => ({
|
|
620
|
+
...method,
|
|
621
|
+
authorized: true
|
|
622
|
+
}))
|
|
623
|
+
}
|
|
624
|
+
])
|
|
625
|
+
) : undefined,
|
|
626
|
+
messages: policies.messages?.map((message) => ({
|
|
627
|
+
...message,
|
|
628
|
+
authorized: true
|
|
629
|
+
}))
|
|
630
|
+
};
|
|
631
|
+
this._rpcUrl = rpc;
|
|
632
|
+
this._chainId = chainId;
|
|
633
|
+
this._keychainUrl = keychainUrl || KEYCHAIN_URL;
|
|
634
|
+
this._backend = new NodeBackend(basePath);
|
|
635
|
+
}
|
|
636
|
+
async username() {
|
|
637
|
+
const sessionStr = await this._backend.get("session");
|
|
638
|
+
if (sessionStr) {
|
|
639
|
+
const session = JSON.parse(sessionStr);
|
|
640
|
+
return session.username;
|
|
641
|
+
}
|
|
642
|
+
return undefined;
|
|
643
|
+
}
|
|
644
|
+
async probe() {
|
|
645
|
+
if (this.account) {
|
|
646
|
+
return this.account;
|
|
647
|
+
}
|
|
648
|
+
const [sessionStr, signerStr] = await Promise.all([
|
|
649
|
+
this._backend.get("session"),
|
|
650
|
+
this._backend.get("signer")
|
|
651
|
+
]);
|
|
652
|
+
if (!sessionStr || !signerStr) {
|
|
653
|
+
return undefined;
|
|
654
|
+
}
|
|
655
|
+
const session = JSON.parse(sessionStr);
|
|
656
|
+
const signer = JSON.parse(signerStr);
|
|
657
|
+
const expirationTime = parseInt(session.expiresAt) * 1e3;
|
|
658
|
+
if (Date.now() >= expirationTime) {
|
|
659
|
+
await this.disconnect();
|
|
660
|
+
return undefined;
|
|
661
|
+
}
|
|
662
|
+
this._username = session.username;
|
|
663
|
+
this.account = new SessionAccount(this, {
|
|
664
|
+
rpcUrl: this._rpcUrl,
|
|
665
|
+
privateKey: signer.privKey,
|
|
666
|
+
address: session.address,
|
|
667
|
+
ownerGuid: session.ownerGuid,
|
|
668
|
+
chainId: this._chainId,
|
|
669
|
+
expiresAt: parseInt(session.expiresAt),
|
|
670
|
+
policies: toWasmPolicies(this._policies)
|
|
671
|
+
});
|
|
672
|
+
return this.account;
|
|
673
|
+
}
|
|
674
|
+
async connect() {
|
|
675
|
+
if (this.account) {
|
|
676
|
+
return this.account;
|
|
677
|
+
}
|
|
678
|
+
const account = await this.probe();
|
|
679
|
+
if (account) {
|
|
680
|
+
return account;
|
|
681
|
+
}
|
|
682
|
+
const pk = starknet.stark.randomAddress();
|
|
683
|
+
const publicKey = starknet.ec.starkCurve.getStarkKey(pk);
|
|
684
|
+
await this._backend.set(
|
|
685
|
+
"signer",
|
|
686
|
+
JSON.stringify({
|
|
687
|
+
privKey: pk,
|
|
688
|
+
pubKey: publicKey
|
|
689
|
+
})
|
|
690
|
+
);
|
|
691
|
+
const redirectUri = await this._backend.getRedirectUri();
|
|
692
|
+
const url = `${this._keychainUrl}/session?public_key=${encodeURIComponent(publicKey)}&redirect_uri=${encodeURIComponent(
|
|
693
|
+
redirectUri
|
|
694
|
+
)}&redirect_query_name=startapp&policies=${encodeURIComponent(
|
|
695
|
+
JSON.stringify(this._policies)
|
|
696
|
+
)}&rpc_url=${encodeURIComponent(this._rpcUrl)}`;
|
|
697
|
+
this._backend.openLink(url);
|
|
698
|
+
const sessionData = await this._backend.waitForCallback();
|
|
699
|
+
if (sessionData) {
|
|
700
|
+
const sessionRegistration = JSON.parse(atob(sessionData));
|
|
701
|
+
sessionRegistration.address = sessionRegistration.address.toLowerCase();
|
|
702
|
+
sessionRegistration.ownerGuid = sessionRegistration.ownerGuid.toLowerCase();
|
|
703
|
+
await this._backend.set("session", JSON.stringify(sessionRegistration));
|
|
704
|
+
return this.probe();
|
|
705
|
+
}
|
|
706
|
+
return undefined;
|
|
707
|
+
}
|
|
708
|
+
async disconnect() {
|
|
709
|
+
await this._backend.delete("signer");
|
|
710
|
+
await this._backend.delete("session");
|
|
711
|
+
this.account = undefined;
|
|
712
|
+
this._username = undefined;
|
|
713
|
+
}
|
|
714
|
+
switchStarknetChain(_chainId) {
|
|
715
|
+
throw new Error("switchStarknetChain not implemented");
|
|
716
|
+
}
|
|
717
|
+
addStarknetChain(_chain) {
|
|
718
|
+
throw new Error("addStarknetChain not implemented");
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
|
|
722
|
+
exports.NotReadyToConnect = NotReadyToConnect;
|
|
723
|
+
exports.ResponseCodes = ResponseCodes;
|
|
724
|
+
exports.default = SessionProvider;
|
|
725
|
+
//# sourceMappingURL=index.cjs.map
|
|
726
|
+
//# sourceMappingURL=index.cjs.map
|