@cartridge/controller 0.5.9 → 0.7.0
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 +53 -115
- package/.turbo/turbo-build.log +54 -116
- 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 +254 -170
- 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 -6
- package/dist/index.js +296 -7666
- 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/node/index.cjs +726 -0
- 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} +521 -216
- package/dist/node/index.js.map +1 -0
- package/dist/policies-DD1aPjQ4.d.cts +21 -0
- 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} +342 -168
- package/dist/session/index.cjs.map +1 -0
- package/dist/session/index.d.cts +38 -0
- package/dist/session/index.d.ts +37 -7
- package/dist/session/index.js +309 -161
- package/dist/session/index.js.map +1 -1
- package/package.json +49 -16
- package/src/controller.ts +44 -15
- package/src/iframe/base.ts +1 -11
- package/src/mutex.ts +22 -0
- 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/policies.ts +49 -0
- package/src/provider.ts +33 -2
- package/src/session/account.ts +2 -1
- package/src/session/provider.ts +123 -10
- package/src/telegram/provider.ts +3 -2
- package/src/types.ts +3 -6
- package/src/utils.ts +4 -1
- package/tsconfig.json +3 -3
- 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 -106
- 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 -122
- package/dist/iframe/base.js.map +0 -1
- package/dist/iframe/index.d.ts +0 -5
- package/dist/iframe/index.js +0 -184
- package/dist/iframe/index.js.map +0 -1
- package/dist/iframe/keychain.d.ts +0 -5
- package/dist/iframe/keychain.js +0 -143
- package/dist/iframe/keychain.js.map +0 -1
- package/dist/iframe/profile.d.ts +0 -5
- package/dist/iframe/profile.js +0 -163
- package/dist/iframe/profile.js.map +0 -1
- package/dist/index.d-BbTUPBeO.d.ts +0 -68
- package/dist/provider.d.ts +0 -22
- package/dist/provider.js +0 -198
- package/dist/provider.js.map +0 -1
- package/dist/session/account.d.ts +0 -37
- package/dist/session/account.js +0 -92
- 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.d.ts +0 -30
- 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 -26
- 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 -18
- package/dist/utils.js +0 -139
- package/dist/utils.js.map +0 -1
|
@@ -1,30 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "@telegram-apps/sdk";
|
|
8
|
-
import { ec, stark } from "starknet";
|
|
1
|
+
import { stark, ec, typedData, TypedDataRevision, hash, WalletAccount, addAddressPadding, CallData } from 'starknet';
|
|
2
|
+
import { CartridgeSessionAccount } from '@cartridge/account-wasm/session';
|
|
3
|
+
import { Permission } from '@starknet-io/types-js';
|
|
4
|
+
import * as fs from 'fs/promises';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import * as http from 'http';
|
|
9
7
|
|
|
10
|
-
// src/
|
|
11
|
-
var KEYCHAIN_URL = "https://x.cartridge.gg";
|
|
12
|
-
|
|
13
|
-
// src/session/account.ts
|
|
14
|
-
import { CartridgeSessionAccount } from "@cartridge/account-wasm/session";
|
|
15
|
-
import { WalletAccount } from "starknet";
|
|
16
|
-
|
|
17
|
-
// src/utils.ts
|
|
18
|
-
import {
|
|
19
|
-
addAddressPadding,
|
|
20
|
-
CallData,
|
|
21
|
-
constants,
|
|
22
|
-
getChecksumAddress,
|
|
23
|
-
hash,
|
|
24
|
-
shortString,
|
|
25
|
-
typedData,
|
|
26
|
-
TypedDataRevision
|
|
27
|
-
} from "starknet";
|
|
8
|
+
// src/node/provider.ts
|
|
28
9
|
function normalizeCalls(calls) {
|
|
29
10
|
return toArray(calls).map((call) => {
|
|
30
11
|
return {
|
|
@@ -39,7 +20,8 @@ function toWasmPolicies(policies) {
|
|
|
39
20
|
...Object.entries(policies.contracts ?? {}).flatMap(
|
|
40
21
|
([target, { methods }]) => toArray(methods).map((m) => ({
|
|
41
22
|
target,
|
|
42
|
-
method: m.entrypoint
|
|
23
|
+
method: m.entrypoint,
|
|
24
|
+
authorized: m.authorized
|
|
43
25
|
}))
|
|
44
26
|
),
|
|
45
27
|
...(policies.messages ?? []).map((p) => {
|
|
@@ -55,7 +37,8 @@ function toWasmPolicies(policies) {
|
|
|
55
37
|
TypedDataRevision.ACTIVE
|
|
56
38
|
);
|
|
57
39
|
return {
|
|
58
|
-
scope_hash: hash.computePoseidonHash(domainHash, typeHash)
|
|
40
|
+
scope_hash: hash.computePoseidonHash(domainHash, typeHash),
|
|
41
|
+
authorized: p.authorized
|
|
59
42
|
};
|
|
60
43
|
})
|
|
61
44
|
];
|
|
@@ -64,8 +47,27 @@ function toArray(val) {
|
|
|
64
47
|
return Array.isArray(val) ? val : [val];
|
|
65
48
|
}
|
|
66
49
|
|
|
67
|
-
// src/
|
|
50
|
+
// src/errors.ts
|
|
51
|
+
var NotReadyToConnect = class _NotReadyToConnect extends Error {
|
|
52
|
+
constructor() {
|
|
53
|
+
super("Not ready to connect");
|
|
54
|
+
Object.setPrototypeOf(this, _NotReadyToConnect.prototype);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// src/types.ts
|
|
59
|
+
var ResponseCodes = /* @__PURE__ */ ((ResponseCodes2) => {
|
|
60
|
+
ResponseCodes2["SUCCESS"] = "SUCCESS";
|
|
61
|
+
ResponseCodes2["NOT_CONNECTED"] = "NOT_CONNECTED";
|
|
62
|
+
ResponseCodes2["ERROR"] = "ERROR";
|
|
63
|
+
ResponseCodes2["CANCELED"] = "CANCELED";
|
|
64
|
+
ResponseCodes2["USER_INTERACTION_REQUIRED"] = "USER_INTERACTION_REQUIRED";
|
|
65
|
+
return ResponseCodes2;
|
|
66
|
+
})(ResponseCodes || {});
|
|
67
|
+
|
|
68
|
+
// src/node/account.ts
|
|
68
69
|
var SessionAccount = class extends WalletAccount {
|
|
70
|
+
controller;
|
|
69
71
|
constructor(provider, {
|
|
70
72
|
rpcUrl,
|
|
71
73
|
privateKey,
|
|
@@ -76,7 +78,8 @@ var SessionAccount = class extends WalletAccount {
|
|
|
76
78
|
policies
|
|
77
79
|
}) {
|
|
78
80
|
super({ nodeUrl: rpcUrl }, provider);
|
|
79
|
-
this.
|
|
81
|
+
this.address = address;
|
|
82
|
+
this.controller = CartridgeSessionAccount.newAsRegistered(
|
|
80
83
|
rpcUrl,
|
|
81
84
|
privateKey,
|
|
82
85
|
address,
|
|
@@ -96,30 +99,34 @@ var SessionAccount = class extends WalletAccount {
|
|
|
96
99
|
* - entrypoint - the entrypoint of the contract
|
|
97
100
|
* - calldata - (defaults to []) the calldata
|
|
98
101
|
* - signature - (defaults to []) the signature
|
|
99
|
-
* @param abis (optional) the abi of the contract for better displaying
|
|
100
102
|
*
|
|
101
103
|
* @returns response from addTransaction
|
|
102
104
|
*/
|
|
103
105
|
async execute(calls) {
|
|
104
|
-
|
|
106
|
+
try {
|
|
107
|
+
const res = await this.controller.executeFromOutside(
|
|
108
|
+
normalizeCalls(calls)
|
|
109
|
+
);
|
|
110
|
+
return res;
|
|
111
|
+
} catch (e) {
|
|
112
|
+
return this.controller.execute(normalizeCalls(calls));
|
|
113
|
+
}
|
|
105
114
|
}
|
|
106
115
|
};
|
|
107
116
|
|
|
108
|
-
// src/
|
|
109
|
-
|
|
110
|
-
Permission
|
|
111
|
-
} from "@starknet-io/types-js";
|
|
117
|
+
// src/constants.ts
|
|
118
|
+
var KEYCHAIN_URL = "https://x.cartridge.gg";
|
|
112
119
|
|
|
113
120
|
// package.json
|
|
114
121
|
var package_default = {
|
|
115
122
|
name: "@cartridge/controller",
|
|
116
|
-
version: "0.
|
|
123
|
+
version: "0.7.0",
|
|
117
124
|
description: "Cartridge Controller",
|
|
118
125
|
module: "dist/index.js",
|
|
119
126
|
types: "dist/index.d.ts",
|
|
120
127
|
type: "module",
|
|
121
128
|
scripts: {
|
|
122
|
-
"build:deps": "tsup
|
|
129
|
+
"build:deps": "tsup",
|
|
123
130
|
build: "pnpm build:deps",
|
|
124
131
|
format: 'prettier --write "src/**/*.ts"',
|
|
125
132
|
"format:check": 'prettier --check "src/**/*.ts"',
|
|
@@ -127,167 +134,240 @@ var package_default = {
|
|
|
127
134
|
version: "pnpm pkg get version"
|
|
128
135
|
},
|
|
129
136
|
exports: {
|
|
130
|
-
".":
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
137
|
+
".": {
|
|
138
|
+
types: "./dist/index.d.ts",
|
|
139
|
+
import: "./dist/index.js",
|
|
140
|
+
require: "./dist/index.cjs"
|
|
141
|
+
},
|
|
142
|
+
"./session": {
|
|
143
|
+
types: "./dist/session/index.d.ts",
|
|
144
|
+
import: "./dist/session/index.js",
|
|
145
|
+
require: "./dist/session/index.cjs"
|
|
146
|
+
},
|
|
147
|
+
"./session/node": {
|
|
148
|
+
types: "./dist/node/index.d.ts",
|
|
149
|
+
import: "./dist/node/index.js",
|
|
150
|
+
require: "./dist/node/index.cjs"
|
|
151
|
+
},
|
|
152
|
+
"./provider": {
|
|
153
|
+
types: "./dist/provider/index.d.ts",
|
|
154
|
+
import: "./dist/provider/index.js"
|
|
155
|
+
},
|
|
156
|
+
"./types": {
|
|
157
|
+
types: "./dist/types/index.d.ts",
|
|
158
|
+
import: "./dist/types/index.js"
|
|
159
|
+
}
|
|
134
160
|
},
|
|
135
161
|
tsup: {
|
|
136
162
|
entry: [
|
|
137
|
-
"src
|
|
163
|
+
"src/index.ts",
|
|
164
|
+
"src/controller.ts",
|
|
165
|
+
"src/lookup.ts",
|
|
166
|
+
"src/session/index.ts",
|
|
167
|
+
"src/node/index.ts"
|
|
138
168
|
],
|
|
139
169
|
format: [
|
|
140
|
-
"esm"
|
|
170
|
+
"esm",
|
|
171
|
+
"cjs"
|
|
141
172
|
],
|
|
142
173
|
splitting: false,
|
|
143
174
|
sourcemap: true,
|
|
144
|
-
clean: true
|
|
175
|
+
clean: true,
|
|
176
|
+
dts: true,
|
|
177
|
+
treeshake: {
|
|
178
|
+
preset: "recommended"
|
|
179
|
+
},
|
|
180
|
+
exports: "named"
|
|
181
|
+
},
|
|
182
|
+
peerDependencies: {
|
|
183
|
+
starknet: "catalog:",
|
|
184
|
+
open: "^10.1.0"
|
|
145
185
|
},
|
|
146
186
|
dependencies: {
|
|
147
187
|
"@cartridge/account-wasm": "workspace:*",
|
|
148
|
-
"@cartridge/penpal": "
|
|
149
|
-
"@starknet-io/types-js": "
|
|
188
|
+
"@cartridge/penpal": "catalog:",
|
|
189
|
+
"@starknet-io/types-js": "catalog:",
|
|
150
190
|
"@telegram-apps/sdk": "^2.4.0",
|
|
151
|
-
base64url: "
|
|
191
|
+
base64url: "catalog:",
|
|
152
192
|
"cbor-x": "^1.5.0",
|
|
153
|
-
"fast-deep-equal": "
|
|
154
|
-
"query-string": "^7.1.1",
|
|
155
|
-
starknet: "^6.11.0"
|
|
193
|
+
"fast-deep-equal": "catalog:"
|
|
156
194
|
},
|
|
157
195
|
devDependencies: {
|
|
158
196
|
"@cartridge/tsconfig": "workspace:*",
|
|
159
197
|
"@types/jest": "^29.5.14",
|
|
160
|
-
"@types/node": "
|
|
198
|
+
"@types/node": "catalog:",
|
|
161
199
|
jest: "^29.7.0",
|
|
200
|
+
prettier: "catalog:",
|
|
162
201
|
"ts-jest": "^29.2.5",
|
|
163
|
-
|
|
202
|
+
tsup: "catalog:",
|
|
203
|
+
typescript: "catalog:"
|
|
164
204
|
}
|
|
165
205
|
};
|
|
166
206
|
|
|
167
207
|
// src/icon.ts
|
|
168
208
|
var icon = "data:image/png;base64,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";
|
|
169
209
|
|
|
210
|
+
// src/mutex.ts
|
|
211
|
+
function releaseStub() {
|
|
212
|
+
}
|
|
213
|
+
var Mutex = class {
|
|
214
|
+
m_lastPromise = Promise.resolve();
|
|
215
|
+
/**
|
|
216
|
+
* Acquire lock
|
|
217
|
+
* @param [bypass=false] option to skip lock acquisition
|
|
218
|
+
*/
|
|
219
|
+
async obtain(bypass = false) {
|
|
220
|
+
let release = releaseStub;
|
|
221
|
+
if (bypass) return release;
|
|
222
|
+
const lastPromise = this.m_lastPromise;
|
|
223
|
+
this.m_lastPromise = new Promise((resolve) => release = resolve);
|
|
224
|
+
await lastPromise;
|
|
225
|
+
return release;
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
|
|
170
229
|
// src/provider.ts
|
|
230
|
+
var mutex = new Mutex();
|
|
171
231
|
var BaseProvider = class {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
232
|
+
id = "controller";
|
|
233
|
+
name = "Controller";
|
|
234
|
+
version = package_default.version;
|
|
235
|
+
icon = icon;
|
|
236
|
+
account;
|
|
237
|
+
subscriptions = [];
|
|
238
|
+
_probePromise = null;
|
|
239
|
+
async safeProbe() {
|
|
240
|
+
if (this.account) {
|
|
241
|
+
return this.account;
|
|
242
|
+
}
|
|
243
|
+
if (this._probePromise) {
|
|
244
|
+
return this._probePromise;
|
|
245
|
+
}
|
|
246
|
+
const release = await mutex.obtain();
|
|
247
|
+
return await new Promise(async (resolve) => {
|
|
248
|
+
try {
|
|
249
|
+
this._probePromise = this.probe();
|
|
250
|
+
const result = await this._probePromise;
|
|
251
|
+
resolve(result);
|
|
252
|
+
} finally {
|
|
253
|
+
this._probePromise = null;
|
|
254
|
+
}
|
|
255
|
+
}).finally(() => {
|
|
256
|
+
release();
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
request = async (call) => {
|
|
260
|
+
switch (call.type) {
|
|
261
|
+
case "wallet_getPermissions":
|
|
262
|
+
await this.safeProbe();
|
|
263
|
+
if (this.account) {
|
|
264
|
+
return [Permission.ACCOUNTS];
|
|
199
265
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
data: "wallet_watchAsset not implemented"
|
|
205
|
-
};
|
|
206
|
-
case "wallet_addStarknetChain": {
|
|
207
|
-
let params2 = call.params;
|
|
208
|
-
return this.addStarknetChain(params2);
|
|
266
|
+
return [];
|
|
267
|
+
case "wallet_requestAccounts": {
|
|
268
|
+
if (this.account) {
|
|
269
|
+
return [this.account.address];
|
|
209
270
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
271
|
+
const silentMode = call.params && call.params.silent_mode;
|
|
272
|
+
this.account = await this.safeProbe();
|
|
273
|
+
if (!this.account && !silentMode) {
|
|
274
|
+
this.account = await this.connect();
|
|
213
275
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
276
|
+
if (this.account) {
|
|
277
|
+
return [this.account.address];
|
|
278
|
+
}
|
|
279
|
+
return [];
|
|
280
|
+
}
|
|
281
|
+
case "wallet_watchAsset":
|
|
282
|
+
throw {
|
|
283
|
+
code: 63,
|
|
284
|
+
message: "An unexpected error occurred",
|
|
285
|
+
data: "wallet_watchAsset not implemented"
|
|
286
|
+
};
|
|
287
|
+
case "wallet_addStarknetChain": {
|
|
288
|
+
let params2 = call.params;
|
|
289
|
+
return this.addStarknetChain(params2);
|
|
290
|
+
}
|
|
291
|
+
case "wallet_switchStarknetChain": {
|
|
292
|
+
let params2 = call.params;
|
|
293
|
+
return this.switchStarknetChain(params2.chainId);
|
|
294
|
+
}
|
|
295
|
+
case "wallet_requestChainId":
|
|
296
|
+
if (!this.account) {
|
|
224
297
|
throw {
|
|
225
298
|
code: 63,
|
|
226
299
|
message: "An unexpected error occurred",
|
|
227
|
-
data: "
|
|
300
|
+
data: "Account not initialized"
|
|
228
301
|
};
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
params.calls.map((call2) => ({
|
|
240
|
-
contractAddress: call2.contract_address,
|
|
241
|
-
entrypoint: call2.entry_point,
|
|
242
|
-
calldata: call2.calldata
|
|
243
|
-
}))
|
|
244
|
-
);
|
|
245
|
-
case "wallet_addDeclareTransaction":
|
|
302
|
+
}
|
|
303
|
+
return await this.account.getChainId();
|
|
304
|
+
case "wallet_deploymentData":
|
|
305
|
+
throw {
|
|
306
|
+
code: 63,
|
|
307
|
+
message: "An unexpected error occurred",
|
|
308
|
+
data: "wallet_deploymentData not implemented"
|
|
309
|
+
};
|
|
310
|
+
case "wallet_addInvokeTransaction":
|
|
311
|
+
if (!this.account) {
|
|
246
312
|
throw {
|
|
247
313
|
code: 63,
|
|
248
314
|
message: "An unexpected error occurred",
|
|
249
|
-
data: "
|
|
315
|
+
data: "Account not initialized"
|
|
250
316
|
};
|
|
251
|
-
case "wallet_signTypedData": {
|
|
252
|
-
if (!this.account) {
|
|
253
|
-
throw {
|
|
254
|
-
code: 63,
|
|
255
|
-
message: "An unexpected error occurred",
|
|
256
|
-
data: "Account not initialized"
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
return await this.account.signMessage(call.params);
|
|
260
317
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
318
|
+
let params = call.params;
|
|
319
|
+
return await this.account.execute(
|
|
320
|
+
params.calls.map((call2) => ({
|
|
321
|
+
contractAddress: call2.contract_address,
|
|
322
|
+
entrypoint: call2.entry_point,
|
|
323
|
+
calldata: call2.calldata
|
|
324
|
+
}))
|
|
325
|
+
);
|
|
326
|
+
case "wallet_addDeclareTransaction":
|
|
327
|
+
throw {
|
|
328
|
+
code: 63,
|
|
329
|
+
message: "An unexpected error occurred",
|
|
330
|
+
data: "wallet_addDeclareTransaction not implemented"
|
|
331
|
+
};
|
|
332
|
+
case "wallet_signTypedData": {
|
|
333
|
+
if (!this.account) {
|
|
266
334
|
throw {
|
|
267
335
|
code: 63,
|
|
268
336
|
message: "An unexpected error occurred",
|
|
269
|
-
data:
|
|
337
|
+
data: "Account not initialized"
|
|
270
338
|
};
|
|
339
|
+
}
|
|
340
|
+
return await this.account.signMessage(call.params);
|
|
271
341
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
342
|
+
case "wallet_supportedSpecs":
|
|
343
|
+
return [];
|
|
344
|
+
case "wallet_supportedWalletApi":
|
|
345
|
+
return [];
|
|
346
|
+
default:
|
|
347
|
+
throw {
|
|
348
|
+
code: 63,
|
|
349
|
+
message: "An unexpected error occurred",
|
|
350
|
+
data: `Unknown RPC call type: ${call.type}`
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
on = (event, handler) => {
|
|
355
|
+
if (event !== "accountsChanged" && event !== "networkChanged") {
|
|
356
|
+
throw new Error(`Unknown event: ${event}`);
|
|
357
|
+
}
|
|
358
|
+
this.subscriptions.push({ type: event, handler });
|
|
359
|
+
};
|
|
360
|
+
off = (event, handler) => {
|
|
361
|
+
if (event !== "accountsChanged" && event !== "networkChanged") {
|
|
362
|
+
throw new Error(`Unknown event: ${event}`);
|
|
363
|
+
}
|
|
364
|
+
const idx = this.subscriptions.findIndex(
|
|
365
|
+
(sub) => sub.type === event && sub.handler === handler
|
|
366
|
+
);
|
|
367
|
+
if (idx >= 0) {
|
|
368
|
+
this.subscriptions.splice(idx, 1);
|
|
369
|
+
}
|
|
370
|
+
};
|
|
291
371
|
emitNetworkChanged(chainId) {
|
|
292
372
|
this.subscriptions.filter((sub) => sub.type === "networkChanged").forEach((sub) => {
|
|
293
373
|
sub.handler(chainId);
|
|
@@ -299,49 +379,311 @@ var BaseProvider = class {
|
|
|
299
379
|
});
|
|
300
380
|
}
|
|
301
381
|
};
|
|
382
|
+
var CallbackServer = class {
|
|
383
|
+
server;
|
|
384
|
+
resolveCallback;
|
|
385
|
+
rejectCallback;
|
|
386
|
+
timeoutId;
|
|
387
|
+
constructor() {
|
|
388
|
+
this.server = http.createServer(this.handleRequest.bind(this));
|
|
389
|
+
this.server.on("error", (error) => {
|
|
390
|
+
console.error("Server error:", error);
|
|
391
|
+
if (this.rejectCallback) {
|
|
392
|
+
this.rejectCallback(error);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
cleanup() {
|
|
397
|
+
if (this.timeoutId) {
|
|
398
|
+
clearTimeout(this.timeoutId);
|
|
399
|
+
}
|
|
400
|
+
this.server.close();
|
|
401
|
+
}
|
|
402
|
+
handleRequest(req, res) {
|
|
403
|
+
if (!req.url?.startsWith("/callback")) {
|
|
404
|
+
res.writeHead(404);
|
|
405
|
+
res.end();
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
const params = new URLSearchParams(req.url.split("?")[1]);
|
|
409
|
+
const session = params.get("startapp");
|
|
410
|
+
if (!session) {
|
|
411
|
+
console.warn("Received callback without session data");
|
|
412
|
+
res.writeHead(400);
|
|
413
|
+
res.end("Missing session data");
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
if (this.resolveCallback) {
|
|
417
|
+
this.resolveCallback(session);
|
|
418
|
+
}
|
|
419
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
420
|
+
res.end(
|
|
421
|
+
"<html><body><script>window.close();</script>Session registered successfully. You can close this window.</body></html>"
|
|
422
|
+
);
|
|
423
|
+
this.cleanup();
|
|
424
|
+
}
|
|
425
|
+
async listen() {
|
|
426
|
+
return new Promise((resolve, reject) => {
|
|
427
|
+
this.server.listen(0, "localhost", () => {
|
|
428
|
+
const address = this.server.address();
|
|
429
|
+
const url = `http://localhost:${address.port}/callback`;
|
|
430
|
+
resolve(url);
|
|
431
|
+
});
|
|
432
|
+
this.server.on("error", reject);
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
async waitForCallback() {
|
|
436
|
+
return new Promise((resolve, reject) => {
|
|
437
|
+
this.resolveCallback = resolve;
|
|
438
|
+
this.rejectCallback = reject;
|
|
439
|
+
this.timeoutId = setTimeout(
|
|
440
|
+
() => {
|
|
441
|
+
console.warn("Callback timeout reached");
|
|
442
|
+
reject(new Error("Callback timeout after 5 minutes"));
|
|
443
|
+
this.cleanup();
|
|
444
|
+
},
|
|
445
|
+
5 * 60 * 1e3
|
|
446
|
+
);
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
// src/node/backend.ts
|
|
452
|
+
var NodeBackend = class {
|
|
453
|
+
basePath;
|
|
454
|
+
sessionFile;
|
|
455
|
+
data = {};
|
|
456
|
+
callbackServer;
|
|
457
|
+
constructor(basePath) {
|
|
458
|
+
if (!basePath) {
|
|
459
|
+
throw new Error("basePath is required for NodeBackend");
|
|
460
|
+
}
|
|
461
|
+
this.basePath = basePath;
|
|
462
|
+
this.sessionFile = path.join(this.basePath, "session.json");
|
|
463
|
+
}
|
|
464
|
+
async ensureDirectoryExists() {
|
|
465
|
+
try {
|
|
466
|
+
await fs.access(this.basePath);
|
|
467
|
+
} catch {
|
|
468
|
+
try {
|
|
469
|
+
await fs.mkdir(this.basePath, { recursive: true });
|
|
470
|
+
} catch (error) {
|
|
471
|
+
throw new Error(
|
|
472
|
+
`Failed to create directory ${this.basePath}: ${error.message}`
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
async loadData() {
|
|
478
|
+
try {
|
|
479
|
+
const content = await fs.readFile(this.sessionFile, "utf-8");
|
|
480
|
+
const parsed = JSON.parse(content);
|
|
481
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
482
|
+
throw new Error("Invalid session data format");
|
|
483
|
+
}
|
|
484
|
+
this.data = parsed;
|
|
485
|
+
} catch (error) {
|
|
486
|
+
if (error instanceof Error) {
|
|
487
|
+
if (error.code !== "ENOENT") {
|
|
488
|
+
throw new Error(`Failed to load session data: ${error.message}`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
this.data = {};
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
async saveData() {
|
|
495
|
+
try {
|
|
496
|
+
await this.ensureDirectoryExists();
|
|
497
|
+
await fs.writeFile(
|
|
498
|
+
this.sessionFile,
|
|
499
|
+
JSON.stringify(this.data, null, 2),
|
|
500
|
+
"utf-8"
|
|
501
|
+
);
|
|
502
|
+
} catch (error) {
|
|
503
|
+
if (error instanceof Error) {
|
|
504
|
+
throw new Error(`Failed to save session data: ${error.message}`);
|
|
505
|
+
}
|
|
506
|
+
throw error;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
async get(key) {
|
|
510
|
+
if (!key) {
|
|
511
|
+
throw new Error("Key is required");
|
|
512
|
+
}
|
|
513
|
+
await this.loadData();
|
|
514
|
+
return this.data[key] ? JSON.stringify(this.data[key]) : null;
|
|
515
|
+
}
|
|
516
|
+
async set(key, value) {
|
|
517
|
+
if (!key) {
|
|
518
|
+
throw new Error("Key is required");
|
|
519
|
+
}
|
|
520
|
+
if (!value) {
|
|
521
|
+
throw new Error("Value is required");
|
|
522
|
+
}
|
|
523
|
+
await this.loadData();
|
|
524
|
+
try {
|
|
525
|
+
this.data[key] = JSON.parse(value);
|
|
526
|
+
await this.saveData();
|
|
527
|
+
} catch (error) {
|
|
528
|
+
if (error instanceof Error) {
|
|
529
|
+
throw new Error(`Failed to set ${key}: ${error.message}`);
|
|
530
|
+
}
|
|
531
|
+
throw error;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
async delete(key) {
|
|
535
|
+
if (!key) {
|
|
536
|
+
throw new Error("Key is required");
|
|
537
|
+
}
|
|
538
|
+
await this.loadData();
|
|
539
|
+
delete this.data[key];
|
|
540
|
+
await this.saveData();
|
|
541
|
+
}
|
|
542
|
+
async getRedirectUri() {
|
|
543
|
+
try {
|
|
544
|
+
this.callbackServer = new CallbackServer();
|
|
545
|
+
return await this.callbackServer.listen();
|
|
546
|
+
} catch (error) {
|
|
547
|
+
if (error instanceof Error) {
|
|
548
|
+
throw new Error(`Failed to start callback server: ${error.message}`);
|
|
549
|
+
}
|
|
550
|
+
throw error;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
async waitForCallback() {
|
|
554
|
+
if (!this.callbackServer) {
|
|
555
|
+
throw new Error("Callback server not initialized");
|
|
556
|
+
}
|
|
557
|
+
return await this.callbackServer.waitForCallback();
|
|
558
|
+
}
|
|
559
|
+
openLink(url) {
|
|
560
|
+
if (!url) {
|
|
561
|
+
throw new Error("URL is required");
|
|
562
|
+
}
|
|
563
|
+
console.log(`
|
|
564
|
+
Open url to authorize session: ${url}`);
|
|
565
|
+
}
|
|
566
|
+
};
|
|
302
567
|
|
|
303
|
-
// src/
|
|
304
|
-
var
|
|
568
|
+
// src/node/provider.ts
|
|
569
|
+
var SessionProvider = class extends BaseProvider {
|
|
570
|
+
id = "controller_session";
|
|
571
|
+
name = "Controller Session";
|
|
572
|
+
_chainId;
|
|
573
|
+
_rpcUrl;
|
|
574
|
+
_username;
|
|
575
|
+
_policies;
|
|
576
|
+
_keychainUrl;
|
|
577
|
+
_backend;
|
|
305
578
|
constructor({
|
|
306
579
|
rpc,
|
|
307
580
|
chainId,
|
|
308
581
|
policies,
|
|
309
|
-
|
|
582
|
+
basePath,
|
|
583
|
+
keychainUrl
|
|
310
584
|
}) {
|
|
311
585
|
super();
|
|
586
|
+
this._policies = {
|
|
587
|
+
verified: false,
|
|
588
|
+
contracts: policies.contracts ? Object.fromEntries(
|
|
589
|
+
Object.entries(policies.contracts).map(([address, contract]) => [
|
|
590
|
+
address,
|
|
591
|
+
{
|
|
592
|
+
...contract,
|
|
593
|
+
methods: contract.methods.map((method) => ({
|
|
594
|
+
...method,
|
|
595
|
+
authorized: true
|
|
596
|
+
}))
|
|
597
|
+
}
|
|
598
|
+
])
|
|
599
|
+
) : undefined,
|
|
600
|
+
messages: policies.messages?.map((message) => ({
|
|
601
|
+
...message,
|
|
602
|
+
authorized: true
|
|
603
|
+
}))
|
|
604
|
+
};
|
|
312
605
|
this._rpcUrl = rpc;
|
|
313
|
-
this._tmaUrl = tmaUrl;
|
|
314
606
|
this._chainId = chainId;
|
|
315
|
-
this.
|
|
316
|
-
|
|
317
|
-
|
|
607
|
+
this._keychainUrl = keychainUrl || KEYCHAIN_URL;
|
|
608
|
+
this._backend = new NodeBackend(basePath);
|
|
609
|
+
}
|
|
610
|
+
async username() {
|
|
611
|
+
const sessionStr = await this._backend.get("session");
|
|
612
|
+
if (sessionStr) {
|
|
613
|
+
const session = JSON.parse(sessionStr);
|
|
614
|
+
return session.username;
|
|
318
615
|
}
|
|
616
|
+
return undefined;
|
|
319
617
|
}
|
|
320
618
|
async probe() {
|
|
321
|
-
|
|
322
|
-
|
|
619
|
+
if (this.account) {
|
|
620
|
+
return this.account;
|
|
621
|
+
}
|
|
622
|
+
const [sessionStr, signerStr] = await Promise.all([
|
|
623
|
+
this._backend.get("session"),
|
|
624
|
+
this._backend.get("signer")
|
|
625
|
+
]);
|
|
626
|
+
if (!sessionStr || !signerStr) {
|
|
627
|
+
return undefined;
|
|
628
|
+
}
|
|
629
|
+
const session = JSON.parse(sessionStr);
|
|
630
|
+
const signer = JSON.parse(signerStr);
|
|
631
|
+
const expirationTime = parseInt(session.expiresAt) * 1e3;
|
|
632
|
+
if (Date.now() >= expirationTime) {
|
|
633
|
+
await this.disconnect();
|
|
634
|
+
return undefined;
|
|
635
|
+
}
|
|
636
|
+
this._username = session.username;
|
|
637
|
+
this.account = new SessionAccount(this, {
|
|
638
|
+
rpcUrl: this._rpcUrl,
|
|
639
|
+
privateKey: signer.privKey,
|
|
640
|
+
address: session.address,
|
|
641
|
+
ownerGuid: session.ownerGuid,
|
|
642
|
+
chainId: this._chainId,
|
|
643
|
+
expiresAt: parseInt(session.expiresAt),
|
|
644
|
+
policies: toWasmPolicies(this._policies)
|
|
645
|
+
});
|
|
646
|
+
return this.account;
|
|
323
647
|
}
|
|
324
648
|
async connect() {
|
|
325
|
-
await this.tryRetrieveFromQueryOrStorage();
|
|
326
649
|
if (this.account) {
|
|
327
|
-
return;
|
|
650
|
+
return this.account;
|
|
651
|
+
}
|
|
652
|
+
const account = await this.probe();
|
|
653
|
+
if (account) {
|
|
654
|
+
return account;
|
|
328
655
|
}
|
|
329
656
|
const pk = stark.randomAddress();
|
|
330
657
|
const publicKey = ec.starkCurve.getStarkKey(pk);
|
|
331
|
-
|
|
332
|
-
"
|
|
658
|
+
await this._backend.set(
|
|
659
|
+
"signer",
|
|
333
660
|
JSON.stringify({
|
|
334
661
|
privKey: pk,
|
|
335
662
|
pubKey: publicKey
|
|
336
663
|
})
|
|
337
664
|
);
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
665
|
+
const redirectUri = await this._backend.getRedirectUri();
|
|
666
|
+
const url = `${this._keychainUrl}/session?public_key=${encodeURIComponent(publicKey)}&redirect_uri=${encodeURIComponent(
|
|
667
|
+
redirectUri
|
|
668
|
+
)}&redirect_query_name=startapp&policies=${encodeURIComponent(
|
|
669
|
+
JSON.stringify(this._policies)
|
|
670
|
+
)}&rpc_url=${encodeURIComponent(this._rpcUrl)}`;
|
|
671
|
+
this._backend.openLink(url);
|
|
672
|
+
const sessionData = await this._backend.waitForCallback();
|
|
673
|
+
if (sessionData) {
|
|
674
|
+
const sessionRegistration = JSON.parse(atob(sessionData));
|
|
675
|
+
sessionRegistration.address = sessionRegistration.address.toLowerCase();
|
|
676
|
+
sessionRegistration.ownerGuid = sessionRegistration.ownerGuid.toLowerCase();
|
|
677
|
+
await this._backend.set("session", JSON.stringify(sessionRegistration));
|
|
678
|
+
return this.probe();
|
|
679
|
+
}
|
|
680
|
+
return undefined;
|
|
681
|
+
}
|
|
682
|
+
async disconnect() {
|
|
683
|
+
await this._backend.delete("signer");
|
|
684
|
+
await this._backend.delete("session");
|
|
685
|
+
this.account = undefined;
|
|
686
|
+
this._username = undefined;
|
|
345
687
|
}
|
|
346
688
|
switchStarknetChain(_chainId) {
|
|
347
689
|
throw new Error("switchStarknetChain not implemented");
|
|
@@ -349,45 +691,8 @@ var TelegramProvider = class extends BaseProvider {
|
|
|
349
691
|
addStarknetChain(_chain) {
|
|
350
692
|
throw new Error("addStarknetChain not implemented");
|
|
351
693
|
}
|
|
352
|
-
disconnect() {
|
|
353
|
-
cloudStorage.deleteItem("sessionSigner");
|
|
354
|
-
cloudStorage.deleteItem("session");
|
|
355
|
-
this.account = void 0;
|
|
356
|
-
this._username = void 0;
|
|
357
|
-
return Promise.resolve();
|
|
358
|
-
}
|
|
359
|
-
async tryRetrieveFromQueryOrStorage() {
|
|
360
|
-
const signer = JSON.parse(await cloudStorage.getItem("sessionSigner"));
|
|
361
|
-
let sessionRegistration = null;
|
|
362
|
-
const launchParams = retrieveLaunchParams();
|
|
363
|
-
const session = launchParams.startParam;
|
|
364
|
-
if (session) {
|
|
365
|
-
sessionRegistration = JSON.parse(atob(session));
|
|
366
|
-
cloudStorage.setItem("session", JSON.stringify(sessionRegistration));
|
|
367
|
-
}
|
|
368
|
-
if (!sessionRegistration) {
|
|
369
|
-
const session2 = await cloudStorage.getItem("session");
|
|
370
|
-
if (session2) {
|
|
371
|
-
sessionRegistration = JSON.parse(session2);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
if (!sessionRegistration) {
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
this._username = sessionRegistration.username;
|
|
378
|
-
this.account = new SessionAccount(this, {
|
|
379
|
-
rpcUrl: this._rpcUrl,
|
|
380
|
-
privateKey: signer.privKey,
|
|
381
|
-
address: sessionRegistration.address,
|
|
382
|
-
ownerGuid: sessionRegistration.ownerGuid,
|
|
383
|
-
chainId: this._chainId,
|
|
384
|
-
expiresAt: parseInt(sessionRegistration.expiresAt),
|
|
385
|
-
policies: toWasmPolicies(this._policies)
|
|
386
|
-
});
|
|
387
|
-
return this.account;
|
|
388
|
-
}
|
|
389
694
|
};
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
//# sourceMappingURL=
|
|
695
|
+
|
|
696
|
+
export { NotReadyToConnect, ResponseCodes, SessionProvider as default };
|
|
697
|
+
//# sourceMappingURL=index.js.map
|
|
698
|
+
//# sourceMappingURL=index.js.map
|