@cartridge/controller 0.1.54 → 0.1.55
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/lib/device.d.ts +57 -0
- package/lib/device.js +130 -0
- package/lib/device.js.map +1 -0
- package/lib/index.d.ts +2 -3
- package/lib/index.js +6 -6
- package/lib/index.js.map +1 -1
- package/lib/types.d.ts +1 -1
- package/lib/webauthn.d.ts +19 -0
- package/lib/webauthn.js +143 -0
- package/lib/webauthn.js.map +1 -0
- package/package.json +1 -1
package/lib/device.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Account, DeployContractPayload, Abi, Call, EstimateFeeDetails, DeployContractResponse as StarknetDeployContractResponse, InvocationsDetails, Signature, typedData, InvokeFunctionResponse, EstimateFee } from "starknet";
|
|
2
|
+
import { Keychain } from "./types";
|
|
3
|
+
import { AsyncMethodReturns } from "@cartridge/penpal";
|
|
4
|
+
declare class DeviceAccount extends Account {
|
|
5
|
+
address: string;
|
|
6
|
+
private keychain;
|
|
7
|
+
private url;
|
|
8
|
+
constructor(address: string, keychain: AsyncMethodReturns<Keychain>, options?: {
|
|
9
|
+
url?: string;
|
|
10
|
+
});
|
|
11
|
+
/**
|
|
12
|
+
* Deploys a given compiled contract (json) to starknet
|
|
13
|
+
*
|
|
14
|
+
* @param payload payload to be deployed containing:
|
|
15
|
+
* - compiled contract code
|
|
16
|
+
* - constructor calldata
|
|
17
|
+
* - address salt
|
|
18
|
+
* @param abi the abi of the contract
|
|
19
|
+
* @returns a confirmation of sending a transaction on the starknet contract
|
|
20
|
+
*/
|
|
21
|
+
deployContract(payload: DeployContractPayload, abi?: Abi): Promise<StarknetDeployContractResponse>;
|
|
22
|
+
/**
|
|
23
|
+
* Estimate Fee for a method on starknet
|
|
24
|
+
*
|
|
25
|
+
* @param calls the invocation object containing:
|
|
26
|
+
* - contractAddress - the address of the contract
|
|
27
|
+
* - entrypoint - the entrypoint of the contract
|
|
28
|
+
* - calldata - (defaults to []) the calldata
|
|
29
|
+
* - signature - (defaults to []) the signature
|
|
30
|
+
*
|
|
31
|
+
* @returns response from addTransaction
|
|
32
|
+
*/
|
|
33
|
+
estimateFee(calls: Call | Call[], details?: EstimateFeeDetails): Promise<EstimateFee>;
|
|
34
|
+
/**
|
|
35
|
+
* Invoke execute function in account contract
|
|
36
|
+
*
|
|
37
|
+
* @param calls the invocation object or an array of them, containing:
|
|
38
|
+
* - contractAddress - the address of the contract
|
|
39
|
+
* - entrypoint - the entrypoint of the contract
|
|
40
|
+
* - calldata - (defaults to []) the calldata
|
|
41
|
+
* - signature - (defaults to []) the signature
|
|
42
|
+
* @param abis (optional) the abi of the contract for better displaying
|
|
43
|
+
*
|
|
44
|
+
* @returns response from addTransaction
|
|
45
|
+
*/
|
|
46
|
+
execute(calls: Call | Call[], abis?: Abi[], transactionsDetail?: InvocationsDetails): Promise<InvokeFunctionResponse>;
|
|
47
|
+
/**
|
|
48
|
+
* Sign an JSON object for off-chain usage with the starknet private key and return the signature
|
|
49
|
+
* This adds a message prefix so it cant be interchanged with transactions
|
|
50
|
+
*
|
|
51
|
+
* @param json - JSON object to be signed
|
|
52
|
+
* @returns the signature of the JSON object
|
|
53
|
+
* @throws {Error} if the JSON object is not a valid JSON
|
|
54
|
+
*/
|
|
55
|
+
signMessage(typedData: typedData.TypedData): Promise<Signature>;
|
|
56
|
+
}
|
|
57
|
+
export default DeviceAccount;
|
package/lib/device.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const starknet_1 = require("starknet");
|
|
16
|
+
const query_string_1 = __importDefault(require("query-string"));
|
|
17
|
+
const signer_1 = require("./signer");
|
|
18
|
+
const constants_1 = require("starknet/constants");
|
|
19
|
+
class DeviceAccount extends starknet_1.Account {
|
|
20
|
+
constructor(address, keychain, options) {
|
|
21
|
+
super(starknet_1.defaultProvider, address, new signer_1.Signer(keychain, options));
|
|
22
|
+
this.url = "https://x.cartridge.gg";
|
|
23
|
+
this.address = address;
|
|
24
|
+
this.keychain = keychain;
|
|
25
|
+
if (options === null || options === void 0 ? void 0 : options.url) {
|
|
26
|
+
this.url = options.url;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Deploys a given compiled contract (json) to starknet
|
|
31
|
+
*
|
|
32
|
+
* @param payload payload to be deployed containing:
|
|
33
|
+
* - compiled contract code
|
|
34
|
+
* - constructor calldata
|
|
35
|
+
* - address salt
|
|
36
|
+
* @param abi the abi of the contract
|
|
37
|
+
* @returns a confirmation of sending a transaction on the starknet contract
|
|
38
|
+
*/
|
|
39
|
+
deployContract(payload, abi) {
|
|
40
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
41
|
+
throw new Error("unimplemented");
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Estimate Fee for a method on starknet
|
|
46
|
+
*
|
|
47
|
+
* @param calls the invocation object containing:
|
|
48
|
+
* - contractAddress - the address of the contract
|
|
49
|
+
* - entrypoint - the entrypoint of the contract
|
|
50
|
+
* - calldata - (defaults to []) the calldata
|
|
51
|
+
* - signature - (defaults to []) the signature
|
|
52
|
+
*
|
|
53
|
+
* @returns response from addTransaction
|
|
54
|
+
*/
|
|
55
|
+
estimateFee(calls, details) {
|
|
56
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
return this.keychain.estimateFee(calls, details);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Invoke execute function in account contract
|
|
62
|
+
*
|
|
63
|
+
* @param calls the invocation object or an array of them, containing:
|
|
64
|
+
* - contractAddress - the address of the contract
|
|
65
|
+
* - entrypoint - the entrypoint of the contract
|
|
66
|
+
* - calldata - (defaults to []) the calldata
|
|
67
|
+
* - signature - (defaults to []) the signature
|
|
68
|
+
* @param abis (optional) the abi of the contract for better displaying
|
|
69
|
+
*
|
|
70
|
+
* @returns response from addTransaction
|
|
71
|
+
*/
|
|
72
|
+
execute(calls, abis, transactionsDetail) {
|
|
73
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
74
|
+
if (!transactionsDetail) {
|
|
75
|
+
transactionsDetail = {};
|
|
76
|
+
}
|
|
77
|
+
if (!transactionsDetail.nonce) {
|
|
78
|
+
transactionsDetail.nonce = 0; //await this.getNonce();
|
|
79
|
+
}
|
|
80
|
+
if (!transactionsDetail.version) {
|
|
81
|
+
transactionsDetail.version = 1;
|
|
82
|
+
}
|
|
83
|
+
if (!transactionsDetail.maxFee) {
|
|
84
|
+
try {
|
|
85
|
+
transactionsDetail.maxFee = "100"; // (await this.estimateFee(calls, { nonce: transactionsDetail.nonce })).suggestedMaxFee
|
|
86
|
+
}
|
|
87
|
+
catch (e) {
|
|
88
|
+
console.error(e);
|
|
89
|
+
throw e;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
return yield this.keychain.execute(calls, abis, transactionsDetail);
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
if (e.message !== "missing scopes") {
|
|
97
|
+
console.error(e);
|
|
98
|
+
throw e;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
window.open(`${this.url}/execute?${query_string_1.default.stringify({
|
|
102
|
+
origin: window.origin,
|
|
103
|
+
calls: JSON.stringify(calls),
|
|
104
|
+
nonce: transactionsDetail.nonce,
|
|
105
|
+
version: transactionsDetail.version,
|
|
106
|
+
maxFee: transactionsDetail.maxFee,
|
|
107
|
+
chainId: constants_1.StarknetChainId.TESTNET,
|
|
108
|
+
})}`, "_blank", "height=650,width=400");
|
|
109
|
+
return this.keychain.execute(calls, abis, transactionsDetail, true);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Sign an JSON object for off-chain usage with the starknet private key and return the signature
|
|
114
|
+
* This adds a message prefix so it cant be interchanged with transactions
|
|
115
|
+
*
|
|
116
|
+
* @param json - JSON object to be signed
|
|
117
|
+
* @returns the signature of the JSON object
|
|
118
|
+
* @throws {Error} if the JSON object is not a valid JSON
|
|
119
|
+
*/
|
|
120
|
+
signMessage(typedData) {
|
|
121
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
122
|
+
window.open(`${this.url}/sign?${query_string_1.default.stringify({
|
|
123
|
+
typedData: JSON.stringify(typedData),
|
|
124
|
+
})}`, "_blank", "height=650,width=400");
|
|
125
|
+
return this.keychain.signMessage(typedData, this.address);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
exports.default = DeviceAccount;
|
|
130
|
+
//# sourceMappingURL=device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.js","sourceRoot":"","sources":["../src/device.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
CHANGED
|
@@ -6,8 +6,6 @@ declare class Controller {
|
|
|
6
6
|
private keychain?;
|
|
7
7
|
private scopes;
|
|
8
8
|
private url;
|
|
9
|
-
private loading;
|
|
10
|
-
private ready_;
|
|
11
9
|
private account;
|
|
12
10
|
constructor(scopes?: Scope[], options?: {
|
|
13
11
|
url?: string;
|
|
@@ -25,6 +23,7 @@ declare class Controller {
|
|
|
25
23
|
connect(): Promise<AccountInterface | null>;
|
|
26
24
|
disconnect(): Promise<void | null>;
|
|
27
25
|
}
|
|
28
|
-
export default Controller;
|
|
29
26
|
export * from "./types";
|
|
30
27
|
export * from "./errors";
|
|
28
|
+
export * from "./webauthn";
|
|
29
|
+
export default Controller;
|
package/lib/index.js
CHANGED
|
@@ -28,13 +28,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
29
|
const query_string_1 = __importDefault(require("query-string"));
|
|
30
30
|
const penpal_1 = require("@cartridge/penpal");
|
|
31
|
-
const
|
|
31
|
+
const device_1 = __importDefault(require("./device"));
|
|
32
32
|
class Controller {
|
|
33
33
|
constructor(scopes, options) {
|
|
34
34
|
this.selector = "cartridge-messenger";
|
|
35
35
|
this.scopes = [];
|
|
36
36
|
this.url = "https://x.cartridge.gg";
|
|
37
|
-
this.loading = true;
|
|
38
37
|
if (scopes) {
|
|
39
38
|
this.scopes = scopes;
|
|
40
39
|
}
|
|
@@ -83,8 +82,8 @@ class Controller {
|
|
|
83
82
|
return null;
|
|
84
83
|
}
|
|
85
84
|
try {
|
|
86
|
-
const { address
|
|
87
|
-
this.account = new
|
|
85
|
+
const { address } = yield this.keychain.probe();
|
|
86
|
+
this.account = new device_1.default(address, this.keychain, {
|
|
88
87
|
url: this.url,
|
|
89
88
|
});
|
|
90
89
|
}
|
|
@@ -129,7 +128,7 @@ class Controller {
|
|
|
129
128
|
scopes: JSON.stringify(this.scopes),
|
|
130
129
|
})}`, "_blank", "height=650,width=400");
|
|
131
130
|
const response = yield this.keychain.connect(this.scopes);
|
|
132
|
-
this.account = new
|
|
131
|
+
this.account = new device_1.default(response.address, this.keychain, {
|
|
133
132
|
url: this.url,
|
|
134
133
|
});
|
|
135
134
|
return this.account;
|
|
@@ -151,7 +150,8 @@ class Controller {
|
|
|
151
150
|
});
|
|
152
151
|
}
|
|
153
152
|
}
|
|
154
|
-
exports.default = Controller;
|
|
155
153
|
__exportStar(require("./types"), exports);
|
|
156
154
|
__exportStar(require("./errors"), exports);
|
|
155
|
+
__exportStar(require("./webauthn"), exports);
|
|
156
|
+
exports.default = Controller;
|
|
157
157
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gEAA8B;AAE9B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Abi, Call, InvocationsDetails, typedData, InvokeFunctionResponse, Signature, InvocationsSignerDetails, EstimateFeeDetails, EstimateFee } from "starknet";
|
|
2
|
-
import { BigNumberish } from "starknet/
|
|
2
|
+
import { BigNumberish } from "starknet/utils/number";
|
|
3
3
|
export declare type Approvals = {
|
|
4
4
|
scopes: Scope[];
|
|
5
5
|
maxFee: BigNumberish;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Abi, Call, InvocationsSignerDetails, Signature, SignerInterface, typedData, Account } from "starknet";
|
|
2
|
+
declare type Assertion = PublicKeyCredential & {
|
|
3
|
+
response: AuthenticatorAssertionResponse;
|
|
4
|
+
};
|
|
5
|
+
export declare class WebauthnSigner implements SignerInterface {
|
|
6
|
+
private credentialId;
|
|
7
|
+
private publicKey;
|
|
8
|
+
constructor(credentialId: string, publicKey: string);
|
|
9
|
+
getPubKey(): Promise<string>;
|
|
10
|
+
sign(hash: string): Promise<Assertion>;
|
|
11
|
+
formatAssertion(assertion: Assertion): Signature;
|
|
12
|
+
hashTransaction(transactions: Call[], transactionsDetail: InvocationsSignerDetails, abis?: Abi[]): string;
|
|
13
|
+
signTransaction(calls: Call[], transactionsDetail: InvocationsSignerDetails, abis?: Abi[]): Promise<Signature>;
|
|
14
|
+
signMessage(td: typedData.TypedData, accountAddress: string): Promise<Signature>;
|
|
15
|
+
}
|
|
16
|
+
declare class WebauthnAccount extends Account {
|
|
17
|
+
constructor(address: string, credentialId: string, publicKey: string);
|
|
18
|
+
}
|
|
19
|
+
export default WebauthnAccount;
|
package/lib/webauthn.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.WebauthnSigner = void 0;
|
|
16
|
+
const starknet_1 = require("starknet");
|
|
17
|
+
const base64url_1 = __importDefault(require("base64url"));
|
|
18
|
+
const BASE = starknet_1.number.toBN(2).pow(86);
|
|
19
|
+
function split(n) {
|
|
20
|
+
const x = n.mod(BASE);
|
|
21
|
+
const y = n.div(BASE).mod(BASE);
|
|
22
|
+
const z = n.div(BASE).div(BASE);
|
|
23
|
+
return { x, y, z };
|
|
24
|
+
}
|
|
25
|
+
function convertUint8ArrayToWordArray(u8Array) {
|
|
26
|
+
var words = [], i = 0, len = u8Array.length;
|
|
27
|
+
while (i < len) {
|
|
28
|
+
words.push(((u8Array[i++] << 24) |
|
|
29
|
+
(u8Array[i++] << 16) |
|
|
30
|
+
(u8Array[i++] << 8) |
|
|
31
|
+
u8Array[i++]) >>>
|
|
32
|
+
0);
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
sigBytes: words.length * 4,
|
|
36
|
+
words: words,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
class WebauthnSigner {
|
|
40
|
+
constructor(credentialId, publicKey) {
|
|
41
|
+
this.credentialId = credentialId;
|
|
42
|
+
this.publicKey = publicKey;
|
|
43
|
+
}
|
|
44
|
+
getPubKey() {
|
|
45
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
return this.publicKey;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
sign(hash) {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
const challenge = Buffer.from(hash.slice(2).padStart(64, "0").slice(0, 64), "hex");
|
|
52
|
+
return (yield navigator.credentials.get({
|
|
53
|
+
publicKey: {
|
|
54
|
+
challenge,
|
|
55
|
+
timeout: 60000,
|
|
56
|
+
rpId: "cartridge.gg",
|
|
57
|
+
allowCredentials: [
|
|
58
|
+
{
|
|
59
|
+
type: "public-key",
|
|
60
|
+
id: base64url_1.default.toBuffer(this.credentialId),
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
userVerification: "required",
|
|
64
|
+
},
|
|
65
|
+
}));
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
formatAssertion(assertion) {
|
|
69
|
+
var authenticatorDataBytes = new Uint8Array(assertion.response.authenticatorData);
|
|
70
|
+
let authenticatorDataRem = 4 - (authenticatorDataBytes.length % 4);
|
|
71
|
+
if (authenticatorDataRem == 4) {
|
|
72
|
+
authenticatorDataRem = 0;
|
|
73
|
+
}
|
|
74
|
+
const authenticatorDataWords = convertUint8ArrayToWordArray(authenticatorDataBytes).words;
|
|
75
|
+
var clientDataJSONBytes = new Uint8Array(assertion.response.clientDataJSON);
|
|
76
|
+
let clientDataJSONRem = 4 - (clientDataJSONBytes.length % 4);
|
|
77
|
+
if (clientDataJSONRem == 4) {
|
|
78
|
+
clientDataJSONRem = 0;
|
|
79
|
+
}
|
|
80
|
+
const clientDataWords = convertUint8ArrayToWordArray(clientDataJSONBytes).words;
|
|
81
|
+
// Convert signature from ASN.1 sequence to "raw" format
|
|
82
|
+
const usignature = new Uint8Array(assertion.response.signature);
|
|
83
|
+
const rStart = usignature[4] === 0 ? 5 : 4;
|
|
84
|
+
const rEnd = rStart + 32;
|
|
85
|
+
const sStart = usignature[rEnd + 2] === 0 ? rEnd + 3 : rEnd + 2;
|
|
86
|
+
const r = starknet_1.number.toBN("0x" + Buffer.from(usignature.slice(rStart, rEnd)).toString("hex"));
|
|
87
|
+
const s = starknet_1.number.toBN("0x" + Buffer.from(usignature.slice(sStart)).toString("hex"));
|
|
88
|
+
const { x: r0, y: r1, z: r2 } = split(r);
|
|
89
|
+
const { x: s0, y: s1, z: s2 } = split(s);
|
|
90
|
+
return [
|
|
91
|
+
"0",
|
|
92
|
+
r0.toString(),
|
|
93
|
+
r1.toString(),
|
|
94
|
+
r2.toString(),
|
|
95
|
+
s0.toString(),
|
|
96
|
+
s1.toString(),
|
|
97
|
+
s2.toString(),
|
|
98
|
+
"9",
|
|
99
|
+
"0",
|
|
100
|
+
`${clientDataWords.length}`,
|
|
101
|
+
`${clientDataJSONRem}`,
|
|
102
|
+
...clientDataWords.map((word) => `${word}`),
|
|
103
|
+
`${authenticatorDataWords.length}`,
|
|
104
|
+
`${authenticatorDataRem}`,
|
|
105
|
+
...authenticatorDataWords.map((word) => `${word}`),
|
|
106
|
+
];
|
|
107
|
+
}
|
|
108
|
+
hashTransaction(transactions, transactionsDetail, abis) {
|
|
109
|
+
if (abis && abis.length !== transactions.length) {
|
|
110
|
+
throw new Error("ABI must be provided for each transaction or no transaction");
|
|
111
|
+
}
|
|
112
|
+
// now use abi to display decoded data somewhere, but as this signer is headless, we can't do that
|
|
113
|
+
const calldata = starknet_1.transaction.fromCallsToExecuteCalldataWithNonce(transactions, transactionsDetail.nonce);
|
|
114
|
+
return starknet_1.hash.calculateTransactionHash(transactionsDetail.walletAddress, transactionsDetail.version, [starknet_1.hash.getSelectorFromName("__execute__")].concat(calldata), transactionsDetail.maxFee, transactionsDetail.chainId, transactionsDetail.nonce);
|
|
115
|
+
}
|
|
116
|
+
signTransaction(calls, transactionsDetail, abis) {
|
|
117
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
118
|
+
if (abis && abis.length !== calls.length) {
|
|
119
|
+
throw new Error("ABI must be provided for each transaction or no transaction");
|
|
120
|
+
}
|
|
121
|
+
// now use abi to display decoded data somewhere, but as this signer is headless, we can't do that
|
|
122
|
+
const calldata = starknet_1.transaction.fromCallsToExecuteCalldataWithNonce(calls, transactionsDetail.nonce);
|
|
123
|
+
const msgHash = starknet_1.hash.calculateTransactionHash(transactionsDetail.walletAddress, transactionsDetail.version, [starknet_1.hash.getSelectorFromName("__execute__")].concat(calldata), transactionsDetail.maxFee, transactionsDetail.chainId, transactionsDetail.nonce);
|
|
124
|
+
const assertion = yield this.sign(msgHash);
|
|
125
|
+
return this.formatAssertion(assertion);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
signMessage(td, accountAddress) {
|
|
129
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
130
|
+
const msgHash = starknet_1.typedData.getMessageHash(td, accountAddress);
|
|
131
|
+
const assertion = yield this.sign(msgHash);
|
|
132
|
+
return this.formatAssertion(assertion);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
exports.WebauthnSigner = WebauthnSigner;
|
|
137
|
+
class WebauthnAccount extends starknet_1.Account {
|
|
138
|
+
constructor(address, credentialId, publicKey) {
|
|
139
|
+
super(starknet_1.defaultProvider, address, new WebauthnSigner(credentialId, publicKey));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
exports.default = WebauthnAccount;
|
|
143
|
+
//# sourceMappingURL=webauthn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webauthn.js","sourceRoot":"","sources":["../src/webauthn.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,uCAYkB;AAClB,0DAAkC;AAGlC,MAAM,IAAI,GAAG,iBAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAMpC,SAAS,KAAK,CAAC,CAAe;IAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACrB,CAAC;AAED,SAAS,4BAA4B,CAAC,OAAmB;IACvD,IAAI,KAAK,GAAG,EAAE,EACZ,CAAC,GAAG,CAAC,EACL,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAEvB,OAAO,CAAC,GAAG,GAAG,EAAE;QACd,KAAK,CAAC,IAAI,CACR,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YACnB,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YACpB,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YACnB,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;YACf,CAAC,CACF,CAAC;KACH;IAED,OAAO;QACL,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC;QAC1B,KAAK,EAAE,KAAK;KACb,CAAC;AACJ,CAAC;AAED,MAAa,cAAc;IAIzB,YAAY,YAAoB,EAAE,SAAiB;QACjD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAEY,SAAS;;YACpB,OAAO,IAAI,CAAC,SAAS,CAAC;QACxB,CAAC;KAAA;IAEY,IAAI,CAAC,IAAY;;YAC5B,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAC3B,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAC5C,KAAK,CACN,CAAC;YACF,OAAO,CAAC,MAAM,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC;gBACtC,SAAS,EAAE;oBACT,SAAS;oBACT,OAAO,EAAE,KAAK;oBACd,IAAI,EAAE,cAAc;oBACpB,gBAAgB,EAAE;wBAChB;4BACE,IAAI,EAAE,YAAY;4BAClB,EAAE,EAAE,mBAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC;yBAC1C;qBACF;oBACD,gBAAgB,EAAE,UAAU;iBAC7B;aACF,CAAC,CAED,CAAC;QACJ,CAAC;KAAA;IAED,eAAe,CAAC,SAAoB;QAClC,IAAI,sBAAsB,GAAG,IAAI,UAAU,CACzC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,CACrC,CAAC;QAEF,IAAI,oBAAoB,GAAG,CAAC,GAAG,CAAC,sBAAsB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACnE,IAAI,oBAAoB,IAAI,CAAC,EAAE;YAC7B,oBAAoB,GAAG,CAAC,CAAC;SAC1B;QACD,MAAM,sBAAsB,GAAG,4BAA4B,CACzD,sBAAsB,CACvB,CAAC,KAAK,CAAC;QAER,IAAI,mBAAmB,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;QAC5E,IAAI,iBAAiB,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7D,IAAI,iBAAiB,IAAI,CAAC,EAAE;YAC1B,iBAAiB,GAAG,CAAC,CAAC;SACvB;QACD,MAAM,eAAe,GACnB,4BAA4B,CAAC,mBAAmB,CAAC,CAAC,KAAK,CAAC;QAE1D,wDAAwD;QACxD,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,GAAG,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;QAEhE,MAAM,CAAC,GAAG,iBAAM,CAAC,IAAI,CACnB,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CACnE,CAAC;QACF,MAAM,CAAC,GAAG,iBAAM,CAAC,IAAI,CACnB,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAC7D,CAAC;QAEF,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACzC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAEzC,OAAO;YACL,GAAG;YACH,EAAE,CAAC,QAAQ,EAAE;YACb,EAAE,CAAC,QAAQ,EAAE;YACb,EAAE,CAAC,QAAQ,EAAE;YACb,EAAE,CAAC,QAAQ,EAAE;YACb,EAAE,CAAC,QAAQ,EAAE;YACb,EAAE,CAAC,QAAQ,EAAE;YACb,GAAG;YACH,GAAG;YACH,GAAG,eAAe,CAAC,MAAM,EAAE;YAC3B,GAAG,iBAAiB,EAAE;YACtB,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC;YAC3C,GAAG,sBAAsB,CAAC,MAAM,EAAE;YAClC,GAAG,oBAAoB,EAAE;YACzB,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC;SACnD,CAAC;IACJ,CAAC;IAEM,eAAe,CACpB,YAAoB,EACpB,kBAA4C,EAC5C,IAAY;QAEZ,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,EAAE;YAC/C,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;SACH;QACD,kGAAkG;QAElG,MAAM,QAAQ,GAAG,sBAAW,CAAC,mCAAmC,CAC9D,YAAY,EACZ,kBAAkB,CAAC,KAAK,CACzB,CAAC;QAEF,OAAO,eAAI,CAAC,wBAAwB,CAClC,kBAAkB,CAAC,aAAa,EAChC,kBAAkB,CAAC,OAAO,EAC1B,CAAC,eAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAC1D,kBAAkB,CAAC,MAAM,EACzB,kBAAkB,CAAC,OAAO,EAC1B,kBAAkB,CAAC,KAAK,CACzB,CAAC;IACJ,CAAC;IAEY,eAAe,CAC1B,KAAa,EACb,kBAA4C,EAC5C,IAAY;;YAEZ,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE;gBACxC,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;aACH;YACD,kGAAkG;YAElG,MAAM,QAAQ,GAAG,sBAAW,CAAC,mCAAmC,CAC9D,KAAK,EACL,kBAAkB,CAAC,KAAK,CACzB,CAAC;YAEF,MAAM,OAAO,GAAG,eAAI,CAAC,wBAAwB,CAC3C,kBAAkB,CAAC,aAAa,EAChC,kBAAkB,CAAC,OAAO,EAC1B,CAAC,eAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAC1D,kBAAkB,CAAC,MAAM,EACzB,kBAAkB,CAAC,OAAO,EAC1B,kBAAkB,CAAC,KAAK,CACzB,CAAC;YAEF,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3C,OAAO,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QACzC,CAAC;KAAA;IAEY,WAAW,CACtB,EAAuB,EACvB,cAAsB;;YAEtB,MAAM,OAAO,GAAG,oBAAS,CAAC,cAAc,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;YAC7D,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3C,OAAO,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QACzC,CAAC;KAAA;CACF;AA7JD,wCA6JC;AAED,MAAM,eAAgB,SAAQ,kBAAO;IACnC,YACE,OAAe,EAAE,YAAoB,EAAE,SAAiB;QAExD,KAAK,CAAC,0BAAe,EAAE,OAAO,EAAE,IAAI,cAAc,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;IAC/E,CAAC;CACF;AAED,kBAAe,eAAe,CAAC"}
|