@msafe/sui3-sdk 0.0.5 → 0.0.6-pre-fdcc3ff.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/dist/index.cjs +258 -969
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -89
- package/dist/index.d.ts +24 -89
- package/dist/index.js +251 -958
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/src/backend/BackendImpl.ts +196 -0
- package/src/backend/PseudoBackend.ts +25 -14
- package/src/backend/interface.ts +10 -10
- package/src/backend/types.ts +0 -21
- package/src/core/CreateHelper.ts +22 -12
- package/src/core/MSafeAccount.ts +9 -5
- package/src/core/MSafeClient.ts +2 -6
- package/src/globals/MSafeGlobals.ts +2 -1
- package/src/globals/const.ts +8 -1
- package/src/types/msafe.ts +0 -20
- package/src/utils/index.ts +0 -1
- package/src/utils/multi-sig.ts +0 -113
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -25,28 +35,21 @@ __export(src_exports, {
|
|
|
25
35
|
Coin: () => Coin,
|
|
26
36
|
CoinHelper: () => CoinHelper,
|
|
27
37
|
CreateHelper: () => CreateHelper,
|
|
38
|
+
DEV_API_URL: () => DEV_API_URL,
|
|
28
39
|
DEV_DATABASE_CONFIG: () => DEV_DATABASE_CONFIG,
|
|
29
40
|
ENV_CONFIGS: () => ENV_CONFIGS,
|
|
30
41
|
Formatter: () => Formatter,
|
|
31
42
|
HexToUint8Array: () => HexToUint8Array,
|
|
32
43
|
IntentionHelper: () => IntentionHelper,
|
|
44
|
+
LOCAL_API_URL: () => LOCAL_API_URL,
|
|
33
45
|
LOCAL_DATABASE_CONFIG: () => LOCAL_DATABASE_CONFIG,
|
|
34
46
|
MAINNET_RPC_URL: () => MAINNET_RPC_URL,
|
|
35
|
-
MAX_OWNER_WITHOUT_NONCE: () => MAX_OWNER_WITHOUT_NONCE,
|
|
36
|
-
MAX_OWNER_WITH_NONCE: () => MAX_OWNER_WITH_NONCE,
|
|
37
|
-
MAX_WEIGHT: () => MAX_WEIGHT,
|
|
38
|
-
MIN_THRESHOLD: () => MIN_THRESHOLD,
|
|
39
|
-
MIN_WEIGHT: () => MIN_WEIGHT,
|
|
40
47
|
MSafeAccount: () => MSafeAccount,
|
|
41
48
|
MSafeClient: () => MSafeClient,
|
|
42
49
|
MSafeEnv: () => MSafeEnv,
|
|
43
50
|
MSafeGlobals: () => MSafeGlobals,
|
|
44
51
|
MessageHelper: () => MessageHelper,
|
|
45
|
-
NONCE_PK_PREFIX: () => NONCE_PK_PREFIX,
|
|
46
|
-
NONCE_PK_WEIGHT: () => NONCE_PK_WEIGHT,
|
|
47
|
-
NONCE_PREFIX_MAX_SIZE: () => NONCE_PREFIX_MAX_SIZE,
|
|
48
52
|
PublicKeySerde: () => PublicKeySerde,
|
|
49
|
-
RawMultiSig: () => RawMultiSig,
|
|
50
53
|
SUI_COIN: () => SUI_COIN,
|
|
51
54
|
SignatureVerifier: () => SignatureVerifier,
|
|
52
55
|
TESTNET_RPC_URL: () => TESTNET_RPC_URL,
|
|
@@ -54,16 +57,31 @@ __export(src_exports, {
|
|
|
54
57
|
Uint8ArrayToHex: () => Uint8ArrayToHex,
|
|
55
58
|
getAllCoins: () => getAllCoins,
|
|
56
59
|
getMSafeConfig: () => getMSafeConfig,
|
|
57
|
-
getMultiSigPublicKey: () => getMultiSigPublicKey,
|
|
58
60
|
getPublicKeyFromChain: () => getPublicKeyFromChain,
|
|
59
|
-
|
|
60
|
-
stringToBuffer: () => stringToBuffer,
|
|
61
|
-
validateMultiSigConfig: () => validateMultiSigConfig
|
|
61
|
+
stringToBuffer: () => stringToBuffer
|
|
62
62
|
});
|
|
63
63
|
module.exports = __toCommonJS(src_exports);
|
|
64
64
|
|
|
65
|
-
// src/
|
|
66
|
-
var
|
|
65
|
+
// src/core/CreateHelper.ts
|
|
66
|
+
var import_sui3_utils = require("@msafe/sui3-utils");
|
|
67
|
+
|
|
68
|
+
// src/utils/crypto.ts
|
|
69
|
+
var import_cryptography = require("@mysten/sui.js/cryptography");
|
|
70
|
+
var import_ed25519 = require("@mysten/sui.js/keypairs/ed25519");
|
|
71
|
+
var import_secp256k1 = require("@mysten/sui.js/keypairs/secp256k1");
|
|
72
|
+
var import_secp256r1 = require("@mysten/sui.js/keypairs/secp256r1");
|
|
73
|
+
var import_verify = require("@mysten/sui.js/verify");
|
|
74
|
+
|
|
75
|
+
// src/utils/buffer.ts
|
|
76
|
+
function stringToBuffer(s) {
|
|
77
|
+
return Buffer.from(s, "utf-8");
|
|
78
|
+
}
|
|
79
|
+
function Uint8ArrayToHex(b) {
|
|
80
|
+
return `0x${Array.prototype.map.call(b, (x) => `0${x.toString(16)}`.slice(-2)).join("")}`;
|
|
81
|
+
}
|
|
82
|
+
function HexToUint8Array(hex) {
|
|
83
|
+
return Uint8Array.from(Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex"));
|
|
84
|
+
}
|
|
67
85
|
|
|
68
86
|
// src/utils/format.ts
|
|
69
87
|
var import_utils2 = require("@mysten/sui.js/utils");
|
|
@@ -139,28 +157,6 @@ var Formatter = class {
|
|
|
139
157
|
}
|
|
140
158
|
};
|
|
141
159
|
|
|
142
|
-
// src/utils/sui.ts
|
|
143
|
-
var import_cryptography2 = require("@mysten/sui.js/cryptography");
|
|
144
|
-
var import_multisig = require("@mysten/sui.js/multisig");
|
|
145
|
-
|
|
146
|
-
// src/utils/crypto.ts
|
|
147
|
-
var import_cryptography = require("@mysten/sui.js/cryptography");
|
|
148
|
-
var import_ed25519 = require("@mysten/sui.js/keypairs/ed25519");
|
|
149
|
-
var import_secp256k1 = require("@mysten/sui.js/keypairs/secp256k1");
|
|
150
|
-
var import_secp256r1 = require("@mysten/sui.js/keypairs/secp256r1");
|
|
151
|
-
var import_verify = require("@mysten/sui.js/verify");
|
|
152
|
-
|
|
153
|
-
// src/utils/buffer.ts
|
|
154
|
-
function stringToBuffer(s) {
|
|
155
|
-
return Buffer.from(s, "utf-8");
|
|
156
|
-
}
|
|
157
|
-
function Uint8ArrayToHex(b) {
|
|
158
|
-
return `0x${Array.prototype.map.call(b, (x) => `0${x.toString(16)}`.slice(-2)).join("")}`;
|
|
159
|
-
}
|
|
160
|
-
function HexToUint8Array(hex) {
|
|
161
|
-
return Uint8Array.from(Buffer.from(hex.startsWith("0x") ? hex.slice(2) : hex, "hex"));
|
|
162
|
-
}
|
|
163
|
-
|
|
164
160
|
// src/utils/crypto.ts
|
|
165
161
|
var SignatureVerifier = class _SignatureVerifier {
|
|
166
162
|
static async getPublicKeyFromSignature(input) {
|
|
@@ -220,7 +216,78 @@ var PublicKeySerde = class {
|
|
|
220
216
|
}
|
|
221
217
|
};
|
|
222
218
|
|
|
219
|
+
// src/core/CreateHelper.ts
|
|
220
|
+
var CreateHelper = class {
|
|
221
|
+
constructor(globals, pkHelper) {
|
|
222
|
+
this.globals = globals;
|
|
223
|
+
this.pkHelper = pkHelper;
|
|
224
|
+
}
|
|
225
|
+
async getPublicKeyBatch(addresses) {
|
|
226
|
+
return this.pkHelper.getPublicKeyBatch(addresses);
|
|
227
|
+
}
|
|
228
|
+
async calculateMSafeAddress(info) {
|
|
229
|
+
const msConfig = await this.reduceCreationInfoToRawConfig(info);
|
|
230
|
+
const ms = new import_sui3_utils.MultisigAccountManager(msConfig);
|
|
231
|
+
return ms.address;
|
|
232
|
+
}
|
|
233
|
+
// Validate the create info and return the msafe address.
|
|
234
|
+
async validateCreateInfo(createInfo) {
|
|
235
|
+
const rawConfig = await this.reduceCreationInfoToRawConfig(createInfo);
|
|
236
|
+
(0, import_sui3_utils.validateCreateAccountRequest)(rawConfig);
|
|
237
|
+
return this.calculateMSafeAddress(createInfo);
|
|
238
|
+
}
|
|
239
|
+
async submitMSafeCreation(creationInfo) {
|
|
240
|
+
const msafeAddress = await this.validateCreateInfo(creationInfo);
|
|
241
|
+
const signingMessage = (0, import_sui3_utils.createAccountCreationMessage)(msafeAddress);
|
|
242
|
+
const signature = await this.globals.wallet.signPersonalMessage({ messageStr: signingMessage });
|
|
243
|
+
await this.submitToBackend(creationInfo, signature.signature);
|
|
244
|
+
return msafeAddress;
|
|
245
|
+
}
|
|
246
|
+
async reduceCreationInfoToRawConfig(info) {
|
|
247
|
+
const publicKeys = await this.getPublicKeyBatch(info.ownerWithWeight.map((oww) => oww.address));
|
|
248
|
+
publicKeys.forEach((pk, i) => {
|
|
249
|
+
if (pk === void 0) {
|
|
250
|
+
throw new Error(`Unknown public key for address: ${info.ownerWithWeight[i].address}`);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
return {
|
|
254
|
+
threshold: info.threshold,
|
|
255
|
+
ownersWithWeight: info.ownerWithWeight.map((owner, i) => ({
|
|
256
|
+
publicKey: publicKeys[i],
|
|
257
|
+
weight: owner.weight
|
|
258
|
+
})),
|
|
259
|
+
creationNonce: info.creationNonce
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
async submitToBackend(createInfo, signature) {
|
|
263
|
+
const pks = await this.pkHelper.getPublicKeyBatch(createInfo.ownerWithWeight.map((owner) => owner.address));
|
|
264
|
+
await this.globals.backend.createMSafeAccount({
|
|
265
|
+
ownersWithWeightPKEncoded: createInfo.ownerWithWeight.map((owner, i) => {
|
|
266
|
+
const publicKeySer = PublicKeySerde.ser(pks[i]);
|
|
267
|
+
return {
|
|
268
|
+
address: owner.address,
|
|
269
|
+
weight: owner.weight,
|
|
270
|
+
publicKeyEncoded: publicKeySer.publicKey,
|
|
271
|
+
schema: publicKeySer.scheme
|
|
272
|
+
};
|
|
273
|
+
}),
|
|
274
|
+
threshold: createInfo.threshold,
|
|
275
|
+
name: createInfo.name,
|
|
276
|
+
// name validation is deferred to backend
|
|
277
|
+
description: createInfo.description,
|
|
278
|
+
// description validation is deferred to backend
|
|
279
|
+
creationNonce: createInfo.creationNonce,
|
|
280
|
+
signature
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
// src/transactions/coin-transfer.ts
|
|
286
|
+
var import_transactions = require("@mysten/sui.js/transactions");
|
|
287
|
+
|
|
223
288
|
// src/utils/sui.ts
|
|
289
|
+
var import_cryptography2 = require("@mysten/sui.js/cryptography");
|
|
290
|
+
var import_multisig = require("@mysten/sui.js/multisig");
|
|
224
291
|
var SUI_COIN = "0x2::sui::SUI";
|
|
225
292
|
async function getPublicKeyFromChain(suiClient, address) {
|
|
226
293
|
let txs;
|
|
@@ -488,165 +555,19 @@ var MessageHelper = class {
|
|
|
488
555
|
}
|
|
489
556
|
};
|
|
490
557
|
|
|
491
|
-
// src/utils/multi-sig.ts
|
|
492
|
-
var import_ed255192 = require("@mysten/sui.js/keypairs/ed25519");
|
|
493
|
-
var import_multisig2 = require("@mysten/sui.js/multisig");
|
|
494
|
-
var NONCE_PK_PREFIX = "maven";
|
|
495
|
-
var NONCE_PREFIX_MAX_SIZE = 16;
|
|
496
|
-
var NONCE_PK_WEIGHT = 1;
|
|
497
|
-
var MAX_WEIGHT = 255;
|
|
498
|
-
var MIN_WEIGHT = 1;
|
|
499
|
-
var MAX_OWNER_WITH_NONCE = 9;
|
|
500
|
-
var MAX_OWNER_WITHOUT_NONCE = 10;
|
|
501
|
-
var MIN_THRESHOLD = 1;
|
|
502
|
-
var RawMultiSig = class _RawMultiSig {
|
|
503
|
-
constructor(config) {
|
|
504
|
-
this.config = config;
|
|
505
|
-
this.rawMsPK = getMultiSigPublicKey(config);
|
|
506
|
-
}
|
|
507
|
-
rawMsPK;
|
|
508
|
-
static fromMSafeAccountInfo(info) {
|
|
509
|
-
const parsed = {
|
|
510
|
-
threshold: info.threshold,
|
|
511
|
-
ownerWithWeight: info.ownersWithWeightPK,
|
|
512
|
-
creationNonce: info.creationNonce
|
|
513
|
-
};
|
|
514
|
-
return new _RawMultiSig(parsed);
|
|
515
|
-
}
|
|
516
|
-
get suiAddress() {
|
|
517
|
-
return this.rawMsPK.toSuiAddress();
|
|
518
|
-
}
|
|
519
|
-
get publicKeys() {
|
|
520
|
-
return this.rawMsPK.getPublicKeys();
|
|
521
|
-
}
|
|
522
|
-
get threshold() {
|
|
523
|
-
return this.config.threshold;
|
|
524
|
-
}
|
|
525
|
-
combinePartialSignatures(signatures) {
|
|
526
|
-
return this.rawMsPK.combinePartialSignatures(signatures);
|
|
527
|
-
}
|
|
528
|
-
async verifyPersonalMessage(messageStr, multiSigSignature) {
|
|
529
|
-
const message = stringToBuffer(messageStr);
|
|
530
|
-
return this.rawMsPK.verifyPersonalMessage(message, multiSigSignature);
|
|
531
|
-
}
|
|
532
|
-
};
|
|
533
|
-
function getMultiSigPublicKey(config) {
|
|
534
|
-
const { ownerWithWeight, threshold, creationNonce } = config;
|
|
535
|
-
const pks = ownerWithWeight.map((pk) => ({
|
|
536
|
-
publicKey: pk.publicKey,
|
|
537
|
-
weight: pk.weight
|
|
538
|
-
}));
|
|
539
|
-
if (creationNonce !== void 0) {
|
|
540
|
-
pks.push({
|
|
541
|
-
publicKey: makeNoncePublicKey(creationNonce),
|
|
542
|
-
weight: NONCE_PK_WEIGHT
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
|
-
return import_multisig2.MultiSigPublicKey.fromPublicKeys({ threshold, publicKeys: pks });
|
|
546
|
-
}
|
|
547
|
-
function makeNoncePublicKey(nonce) {
|
|
548
|
-
const buffer = new ArrayBuffer(import_ed255192.Ed25519PublicKey.SIZE);
|
|
549
|
-
const textEncoder = new TextEncoder();
|
|
550
|
-
textEncoder.encodeInto(NONCE_PK_PREFIX, new Uint8Array(buffer, 0, NONCE_PREFIX_MAX_SIZE));
|
|
551
|
-
const nonceView = new DataView(buffer, NONCE_PREFIX_MAX_SIZE, 4);
|
|
552
|
-
nonceView.setUint32(0, nonce, true);
|
|
553
|
-
return new import_ed255192.Ed25519PublicKey(new Uint8Array(buffer));
|
|
554
|
-
}
|
|
555
|
-
function validateMultiSigConfig(config) {
|
|
556
|
-
config.ownerWithWeight.forEach((pk) => {
|
|
557
|
-
const { weight } = pk;
|
|
558
|
-
if (weight < MIN_WEIGHT || weight > MAX_WEIGHT) {
|
|
559
|
-
throw new Error(`Invalid multi-sig weight: ${weight} (1-${MAX_WEIGHT})`);
|
|
560
|
-
}
|
|
561
|
-
});
|
|
562
|
-
const totalWeight = config.ownerWithWeight.reduce((s, pk) => s + pk.weight, 0);
|
|
563
|
-
if (config.threshold > totalWeight) {
|
|
564
|
-
throw new Error("Threshold is larger than total weight");
|
|
565
|
-
}
|
|
566
|
-
if (config.threshold < MIN_THRESHOLD) {
|
|
567
|
-
throw new Error("Threshold is smaller than 1");
|
|
568
|
-
}
|
|
569
|
-
const maxOwner = config.creationNonce === void 0 ? MAX_OWNER_WITHOUT_NONCE : MAX_OWNER_WITH_NONCE;
|
|
570
|
-
if (config.ownerWithWeight.length > maxOwner) {
|
|
571
|
-
throw new Error("Owner number bigger than upper cap");
|
|
572
|
-
}
|
|
573
|
-
const addressSet = new Set(config.ownerWithWeight.map((pk) => pk.publicKey.toSuiAddress()));
|
|
574
|
-
if (addressSet.size !== config.ownerWithWeight.length) {
|
|
575
|
-
throw new Error("Duplicate address detected");
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
// src/core/CreateHelper.ts
|
|
580
|
-
var CreateHelper = class {
|
|
581
|
-
constructor(globals, pkHelper) {
|
|
582
|
-
this.globals = globals;
|
|
583
|
-
this.pkHelper = pkHelper;
|
|
584
|
-
}
|
|
585
|
-
async getPublicKeyBatch(addresses) {
|
|
586
|
-
return this.pkHelper.getPublicKeyBatch(addresses);
|
|
587
|
-
}
|
|
588
|
-
async calculateMSafeAddress(info) {
|
|
589
|
-
const msConfig = await this.reduceCreationInfoToRawConfig(info);
|
|
590
|
-
const ms = new RawMultiSig(msConfig);
|
|
591
|
-
return ms.suiAddress;
|
|
592
|
-
}
|
|
593
|
-
// Validate the create info and return the msafe address.
|
|
594
|
-
async validateCreateInfo(createInfo) {
|
|
595
|
-
const rawConfig = await this.reduceCreationInfoToRawConfig(createInfo);
|
|
596
|
-
validateMultiSigConfig(rawConfig);
|
|
597
|
-
return this.calculateMSafeAddress(createInfo);
|
|
598
|
-
}
|
|
599
|
-
async submitMSafeCreation(creationInfo) {
|
|
600
|
-
const msafeAddress = await this.validateCreateInfo(creationInfo);
|
|
601
|
-
const signingMessage = MessageHelper.createMSafeMessage(msafeAddress);
|
|
602
|
-
const signature = await this.globals.wallet.signPersonalMessage({ messageStr: signingMessage });
|
|
603
|
-
await this.submitToBackend(creationInfo, signature.signature);
|
|
604
|
-
return msafeAddress;
|
|
605
|
-
}
|
|
606
|
-
async reduceCreationInfoToRawConfig(info) {
|
|
607
|
-
const publicKeys = await this.getPublicKeyBatch(info.ownerWithWeight.map((oww) => oww.address));
|
|
608
|
-
publicKeys.forEach((pk, i) => {
|
|
609
|
-
if (pk === void 0) {
|
|
610
|
-
throw new Error(`Unknown public key for address: ${info.ownerWithWeight[i].address}`);
|
|
611
|
-
}
|
|
612
|
-
});
|
|
613
|
-
return {
|
|
614
|
-
threshold: info.threshold,
|
|
615
|
-
ownerWithWeight: info.ownerWithWeight.map((owner, i) => ({
|
|
616
|
-
publicKey: publicKeys[i],
|
|
617
|
-
weight: owner.weight
|
|
618
|
-
})),
|
|
619
|
-
creationNonce: info.creationNonce
|
|
620
|
-
};
|
|
621
|
-
}
|
|
622
|
-
async submitToBackend(createInfo, signature) {
|
|
623
|
-
const pks = await this.pkHelper.getPublicKeyBatch(createInfo.ownerWithWeight.map((owner) => owner.address));
|
|
624
|
-
await this.globals.backend.createMSafeAccount({
|
|
625
|
-
ownerWithWeight: createInfo.ownerWithWeight.map((owner, i) => ({
|
|
626
|
-
address: owner.address,
|
|
627
|
-
weight: owner.weight,
|
|
628
|
-
publicKey: pks[i]
|
|
629
|
-
// PublicKey has been verified.
|
|
630
|
-
})),
|
|
631
|
-
threshold: createInfo.threshold,
|
|
632
|
-
name: createInfo.name,
|
|
633
|
-
// name validation is deferred to backend
|
|
634
|
-
description: createInfo.description,
|
|
635
|
-
// description validation is deferred to backend
|
|
636
|
-
creationNonce: createInfo.creationNonce,
|
|
637
|
-
signature
|
|
638
|
-
});
|
|
639
|
-
}
|
|
640
|
-
};
|
|
641
|
-
|
|
642
558
|
// src/core/MSafeAccount.ts
|
|
559
|
+
var import_sui3_utils2 = require("@msafe/sui3-utils");
|
|
643
560
|
var MSafeAccount = class _MSafeAccount {
|
|
644
561
|
constructor(globals, info) {
|
|
645
562
|
this.globals = globals;
|
|
646
563
|
this.info = info;
|
|
647
|
-
this.
|
|
564
|
+
this.multisigManager = new import_sui3_utils2.MultisigAccountManager({
|
|
565
|
+
threshold: info.threshold,
|
|
566
|
+
ownersWithWeight: info.ownersWithWeightPK,
|
|
567
|
+
creationNonce: info.creationNonce
|
|
568
|
+
});
|
|
648
569
|
}
|
|
649
|
-
|
|
570
|
+
multisigManager;
|
|
650
571
|
static async new(globals, address) {
|
|
651
572
|
const info = await globals.backend.getMSafeAccountInfo(address);
|
|
652
573
|
return new _MSafeAccount(globals, info);
|
|
@@ -755,7 +676,7 @@ var MSafeAccount = class _MSafeAccount {
|
|
|
755
676
|
sigs.push(signature);
|
|
756
677
|
}
|
|
757
678
|
}
|
|
758
|
-
const multiSignature = this.
|
|
679
|
+
const multiSignature = this.multisigManager.combinePartialSignatures(sigs);
|
|
759
680
|
return this.suiClient.executeTransactionBlock({
|
|
760
681
|
transactionBlock: HexToUint8Array(pending.payload),
|
|
761
682
|
signature: multiSignature,
|
|
@@ -848,762 +769,6 @@ var PublicKeyHelper = class {
|
|
|
848
769
|
// src/globals/MSafeGlobals.ts
|
|
849
770
|
var import_client = require("@mysten/sui.js/client");
|
|
850
771
|
|
|
851
|
-
// src/backend/PseudoBackend.ts
|
|
852
|
-
var import_reflect_metadata2 = require("reflect-metadata");
|
|
853
|
-
var import_typeorm = require("typeorm");
|
|
854
|
-
|
|
855
|
-
// src/backend/CoreDatabase.ts
|
|
856
|
-
var import_reflect_metadata = require("reflect-metadata");
|
|
857
|
-
var import_core = require("@msafe/sui3-model/core");
|
|
858
|
-
var WALLET_TYPE_KEY = "wallet_type";
|
|
859
|
-
var CoreDB = class _CoreDB {
|
|
860
|
-
constructor(coreModel) {
|
|
861
|
-
this.coreModel = coreModel;
|
|
862
|
-
}
|
|
863
|
-
static async New(dbConfig) {
|
|
864
|
-
const core = await import_core.CoreModel.New(dbConfig);
|
|
865
|
-
return new _CoreDB(core);
|
|
866
|
-
}
|
|
867
|
-
async upsertUser(input) {
|
|
868
|
-
const currentUser = await this.coreModel.user.findOneBy({
|
|
869
|
-
address: input.address
|
|
870
|
-
});
|
|
871
|
-
if (currentUser !== null) {
|
|
872
|
-
currentUser.lastLogin = input.lastLogin;
|
|
873
|
-
await this.coreModel.user.save(currentUser);
|
|
874
|
-
} else {
|
|
875
|
-
const serializedPublicKey = PublicKeySerde.ser(input.publicKey);
|
|
876
|
-
const user = {
|
|
877
|
-
address: input.address,
|
|
878
|
-
publicKey: serializedPublicKey.publicKey,
|
|
879
|
-
schema: serializedPublicKey.scheme,
|
|
880
|
-
nonce: 0,
|
|
881
|
-
lastLogin: /* @__PURE__ */ new Date()
|
|
882
|
-
};
|
|
883
|
-
await this.coreModel.user.save(user);
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
async updateUserWalletType(input) {
|
|
887
|
-
const exist = await this.coreModel.userSetting.findOneBy({
|
|
888
|
-
userAddress: input.address,
|
|
889
|
-
key: WALLET_TYPE_KEY
|
|
890
|
-
});
|
|
891
|
-
const walletType = input.walletType.trim();
|
|
892
|
-
if (exist === null || exist.value !== walletType) {
|
|
893
|
-
const userSetting = {
|
|
894
|
-
userAddress: input.address,
|
|
895
|
-
key: WALLET_TYPE_KEY,
|
|
896
|
-
value: walletType
|
|
897
|
-
};
|
|
898
|
-
await this.coreModel.userSetting.save(userSetting);
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
};
|
|
902
|
-
|
|
903
|
-
// src/backend/PseudoBackend.ts
|
|
904
|
-
var PseudoBackend = class _PseudoBackend {
|
|
905
|
-
constructor(db, _suiClient) {
|
|
906
|
-
this.db = db;
|
|
907
|
-
this._suiClient = _suiClient;
|
|
908
|
-
}
|
|
909
|
-
_token;
|
|
910
|
-
static async New(dbConfig, suiClient) {
|
|
911
|
-
const db = await CoreDB.New(dbConfig);
|
|
912
|
-
return new _PseudoBackend(db, suiClient);
|
|
913
|
-
}
|
|
914
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars,unused-imports/no-unused-vars
|
|
915
|
-
async isJWTTokenValid(_jwt) {
|
|
916
|
-
return true;
|
|
917
|
-
}
|
|
918
|
-
async authSign(input) {
|
|
919
|
-
const timestamp = MessageHelper.deWelcomeMessage(input.message);
|
|
920
|
-
if (!timestamp) {
|
|
921
|
-
throw new Error("Invalid welcome message");
|
|
922
|
-
}
|
|
923
|
-
const date = Date.parse(timestamp);
|
|
924
|
-
if ((/* @__PURE__ */ new Date()).getTime() - date < 0) {
|
|
925
|
-
throw new Error("Invalid timestamp");
|
|
926
|
-
}
|
|
927
|
-
if ((/* @__PURE__ */ new Date()).getTime() - date > 10 * 1e3) {
|
|
928
|
-
throw new Error("Signing message expired");
|
|
929
|
-
}
|
|
930
|
-
const publicKey = await SignatureVerifier.getPublicKeyFromPersonalSignature({
|
|
931
|
-
messageStr: input.message,
|
|
932
|
-
signature: input.signature
|
|
933
|
-
});
|
|
934
|
-
if (!Formatter.isSuiAddressEqual(input.address, publicKey.toSuiAddress())) {
|
|
935
|
-
throw new Error("Invalid signature");
|
|
936
|
-
}
|
|
937
|
-
await this.db.upsertUser({
|
|
938
|
-
address: input.address,
|
|
939
|
-
publicKey,
|
|
940
|
-
lastLogin: /* @__PURE__ */ new Date()
|
|
941
|
-
});
|
|
942
|
-
await this.db.updateUserWalletType({
|
|
943
|
-
address: input.address,
|
|
944
|
-
walletType: input.walletType
|
|
945
|
-
});
|
|
946
|
-
this._token = "";
|
|
947
|
-
return this._token;
|
|
948
|
-
}
|
|
949
|
-
setJWTToken(token) {
|
|
950
|
-
this._token = token;
|
|
951
|
-
}
|
|
952
|
-
async getPublicKey(address) {
|
|
953
|
-
const user = await this.model.user.findOneBy({
|
|
954
|
-
address
|
|
955
|
-
});
|
|
956
|
-
if (user === null) {
|
|
957
|
-
return void 0;
|
|
958
|
-
}
|
|
959
|
-
return PublicKeySerde.de({
|
|
960
|
-
publicKey: user.publicKey,
|
|
961
|
-
scheme: user.schema
|
|
962
|
-
});
|
|
963
|
-
}
|
|
964
|
-
async getPublicKeyBatch(addresses) {
|
|
965
|
-
const res = [];
|
|
966
|
-
for (let i = 0; i < addresses.length; i++) {
|
|
967
|
-
const address = addresses[i];
|
|
968
|
-
const user = await this.getUser(address);
|
|
969
|
-
res.push(
|
|
970
|
-
user ? PublicKeySerde.de({
|
|
971
|
-
publicKey: user.publicKey,
|
|
972
|
-
scheme: user.schema
|
|
973
|
-
}) : void 0
|
|
974
|
-
);
|
|
975
|
-
}
|
|
976
|
-
return res;
|
|
977
|
-
}
|
|
978
|
-
async createMSafeAccount(input) {
|
|
979
|
-
const ms = new RawMultiSig(input);
|
|
980
|
-
const msafeAddr = ms.suiAddress;
|
|
981
|
-
const signingMsg = MessageHelper.createMSafeMessage(msafeAddr);
|
|
982
|
-
const targetAddr = input.ownerWithWeight[0].address;
|
|
983
|
-
const verifyResult = await SignatureVerifier.verifyPersonalSignature({
|
|
984
|
-
messageStr: signingMsg,
|
|
985
|
-
signature: input.signature,
|
|
986
|
-
targetAddress: targetAddr
|
|
987
|
-
});
|
|
988
|
-
if (!verifyResult) {
|
|
989
|
-
throw new Error("Signature verification failed");
|
|
990
|
-
}
|
|
991
|
-
if (input.name.length > 128) {
|
|
992
|
-
throw new Error("Name too long");
|
|
993
|
-
}
|
|
994
|
-
if (input.description && input.description.length > 512) {
|
|
995
|
-
throw new Error("Description too long");
|
|
996
|
-
}
|
|
997
|
-
const creatorAddress = input.ownerWithWeight[0].address;
|
|
998
|
-
const creator = await this.getUser(creatorAddress);
|
|
999
|
-
if (creator === null) {
|
|
1000
|
-
throw new Error("Creator not found");
|
|
1001
|
-
}
|
|
1002
|
-
if (creator.nonce !== input.creationNonce) {
|
|
1003
|
-
throw new Error("Nonce not match");
|
|
1004
|
-
}
|
|
1005
|
-
const msafeExistCheck = await this.model.msafe.findOneBy({
|
|
1006
|
-
address: msafeAddr
|
|
1007
|
-
});
|
|
1008
|
-
if (msafeExistCheck !== null) {
|
|
1009
|
-
throw new Error("MSafe already exist in database");
|
|
1010
|
-
}
|
|
1011
|
-
input.ownerWithWeight.forEach((ownerInfo) => {
|
|
1012
|
-
if (!Formatter.isSuiAddressEqual(ownerInfo.address, ownerInfo.publicKey.toSuiAddress())) {
|
|
1013
|
-
throw new Error("Sui address public key not match");
|
|
1014
|
-
}
|
|
1015
|
-
});
|
|
1016
|
-
for (let i = 0; i !== input.ownerWithWeight.length; i++) {
|
|
1017
|
-
const ownerInfo = input.ownerWithWeight[i];
|
|
1018
|
-
if (i !== 0) {
|
|
1019
|
-
const coManager = await this.getUser(ownerInfo.address);
|
|
1020
|
-
const serPK = PublicKeySerde.ser(ownerInfo.publicKey);
|
|
1021
|
-
if (coManager === null) {
|
|
1022
|
-
const user = {
|
|
1023
|
-
address: ownerInfo.address,
|
|
1024
|
-
publicKey: serPK.publicKey,
|
|
1025
|
-
schema: serPK.scheme,
|
|
1026
|
-
nonce: 0,
|
|
1027
|
-
lastLogin: /* @__PURE__ */ new Date()
|
|
1028
|
-
};
|
|
1029
|
-
await this.model.user.save(user);
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
const userMSafe = {
|
|
1033
|
-
userAddress: ownerInfo.address,
|
|
1034
|
-
msafeAddress: msafeAddr,
|
|
1035
|
-
index: i,
|
|
1036
|
-
weight: ownerInfo.weight,
|
|
1037
|
-
status: i === 0 ? "active" : "pending"
|
|
1038
|
-
};
|
|
1039
|
-
await this.model.userMSafe.save(userMSafe);
|
|
1040
|
-
}
|
|
1041
|
-
const creationNonce = creator.nonce;
|
|
1042
|
-
creator.nonce++;
|
|
1043
|
-
await this.model.user.save(creator);
|
|
1044
|
-
const msafe = {
|
|
1045
|
-
address: msafeAddr,
|
|
1046
|
-
creationNonce,
|
|
1047
|
-
creator: creatorAddress,
|
|
1048
|
-
name: input.name,
|
|
1049
|
-
description: input.description,
|
|
1050
|
-
threshold: input.threshold
|
|
1051
|
-
};
|
|
1052
|
-
await this.model.msafe.save(msafe);
|
|
1053
|
-
}
|
|
1054
|
-
async getMSafeAccountInfo(msafeAddress) {
|
|
1055
|
-
const msafe = await this.model.msafe.findOneBy({ address: msafeAddress });
|
|
1056
|
-
if (msafe === null) {
|
|
1057
|
-
throw new Error("MSafe not found");
|
|
1058
|
-
}
|
|
1059
|
-
const userMSafes = await this.model.userMSafe.find({
|
|
1060
|
-
where: {
|
|
1061
|
-
msafeAddress
|
|
1062
|
-
},
|
|
1063
|
-
order: {
|
|
1064
|
-
index: "asc"
|
|
1065
|
-
}
|
|
1066
|
-
});
|
|
1067
|
-
if (userMSafes.length === 0) {
|
|
1068
|
-
throw new Error("MSafe does not have user info.");
|
|
1069
|
-
}
|
|
1070
|
-
const users = await Promise.all(userMSafes.map((um) => this.getUser(um.userAddress)));
|
|
1071
|
-
users.forEach((user) => {
|
|
1072
|
-
if (user === null) {
|
|
1073
|
-
throw new Error("User not found");
|
|
1074
|
-
}
|
|
1075
|
-
});
|
|
1076
|
-
const ownersWithWeightPK = userMSafes.map((userMSafe, i) => ({
|
|
1077
|
-
address: userMSafe.userAddress,
|
|
1078
|
-
weight: userMSafe.weight,
|
|
1079
|
-
publicKey: PublicKeySerde.de({ publicKey: users[i].publicKey, scheme: users[i].schema })
|
|
1080
|
-
}));
|
|
1081
|
-
return {
|
|
1082
|
-
address: msafeAddress,
|
|
1083
|
-
ownersWithWeightPK,
|
|
1084
|
-
threshold: msafe.threshold,
|
|
1085
|
-
name: msafe.name,
|
|
1086
|
-
description: msafe.description,
|
|
1087
|
-
creationNonce: msafe.creationNonce
|
|
1088
|
-
};
|
|
1089
|
-
}
|
|
1090
|
-
async getUserInfo(userAddress) {
|
|
1091
|
-
const user = await this.getUser(userAddress);
|
|
1092
|
-
if (user === null) {
|
|
1093
|
-
throw new Error("404: user not found");
|
|
1094
|
-
}
|
|
1095
|
-
const msafeAccounts = await this.model.userMSafe.findBy({ userAddress });
|
|
1096
|
-
const ownedMSafe = await Promise.all(
|
|
1097
|
-
msafeAccounts.map(async (msafeAccount) => this.getMSafeAccountInfo(msafeAccount.msafeAddress))
|
|
1098
|
-
);
|
|
1099
|
-
return {
|
|
1100
|
-
address: userAddress,
|
|
1101
|
-
publicKey: user.publicKey,
|
|
1102
|
-
schema: user.schema,
|
|
1103
|
-
creationNonce: user.nonce,
|
|
1104
|
-
ownedMSafe
|
|
1105
|
-
};
|
|
1106
|
-
}
|
|
1107
|
-
async getPendingTransactions(msafeAddress) {
|
|
1108
|
-
const pendings = await this.db.coreModel.pendingTransaction.findBy({
|
|
1109
|
-
msafeAddress
|
|
1110
|
-
});
|
|
1111
|
-
if (pendings.length === 0) {
|
|
1112
|
-
return [];
|
|
1113
|
-
}
|
|
1114
|
-
const votes = await Promise.all(
|
|
1115
|
-
pendings.map((pending) => this.db.coreModel.userVote.findBy({ txDigest: pending.digest, isValid: true }))
|
|
1116
|
-
);
|
|
1117
|
-
const intention = await this.model.transactionIntention.findOneBy({
|
|
1118
|
-
msafeAddress,
|
|
1119
|
-
sequenceNumber: pendings[0].sequenceNumber
|
|
1120
|
-
});
|
|
1121
|
-
if (intention === null) {
|
|
1122
|
-
throw new Error("Intention not found");
|
|
1123
|
-
}
|
|
1124
|
-
const intent = IntentionHelper.de(intention.data);
|
|
1125
|
-
return pendings.map((pending, i) => ({
|
|
1126
|
-
digest: pending.digest,
|
|
1127
|
-
payload: pending.payload,
|
|
1128
|
-
msafeAddress: pending.msafeAddress,
|
|
1129
|
-
isRejectTx: pending.isRejectTx,
|
|
1130
|
-
creator: pending.creator,
|
|
1131
|
-
createdAt: pending.createdAt,
|
|
1132
|
-
votes: votes[i].map((vote) => ({
|
|
1133
|
-
userAddress: vote.userAddress,
|
|
1134
|
-
signature: vote.signature,
|
|
1135
|
-
timestamp: vote.updatedAt
|
|
1136
|
-
})),
|
|
1137
|
-
sequenceNumber: pending.sequenceNumber,
|
|
1138
|
-
intention: pending.isRejectTx ? void 0 : intent
|
|
1139
|
-
}));
|
|
1140
|
-
}
|
|
1141
|
-
async getCurrentSequenceNumber(msafeAddress) {
|
|
1142
|
-
const maxSNHistory = await this.model.historyTransaction.findOne({
|
|
1143
|
-
where: { msafeAddress },
|
|
1144
|
-
order: { sequenceNumber: "desc" }
|
|
1145
|
-
});
|
|
1146
|
-
return maxSNHistory === null ? 0 : maxSNHistory.sequenceNumber + 1;
|
|
1147
|
-
}
|
|
1148
|
-
async getNextSequenceNumber(msafeAddress) {
|
|
1149
|
-
const maxSNIntention = await this.model.transactionIntention.findOne({
|
|
1150
|
-
where: { msafeAddress },
|
|
1151
|
-
order: { sequenceNumber: "desc" }
|
|
1152
|
-
});
|
|
1153
|
-
return maxSNIntention === null ? 0 : maxSNIntention.sequenceNumber + 1;
|
|
1154
|
-
}
|
|
1155
|
-
async getHistoryTransactions(msafeAddress) {
|
|
1156
|
-
const transactions = await this.db.coreModel.historyTransaction.find({
|
|
1157
|
-
where: {
|
|
1158
|
-
msafeAddress
|
|
1159
|
-
},
|
|
1160
|
-
order: { sequenceNumber: "desc" }
|
|
1161
|
-
});
|
|
1162
|
-
const votes = await Promise.all(
|
|
1163
|
-
transactions.map(
|
|
1164
|
-
(tx) => this.db.coreModel.userVote.findBy({
|
|
1165
|
-
txDigest: tx.digest,
|
|
1166
|
-
isValid: true
|
|
1167
|
-
})
|
|
1168
|
-
)
|
|
1169
|
-
);
|
|
1170
|
-
return transactions.map((tx, i) => ({
|
|
1171
|
-
digest: tx.digest,
|
|
1172
|
-
payload: tx.payload,
|
|
1173
|
-
msafeAddress: tx.msafeAddress,
|
|
1174
|
-
isRejectTx: tx.isRejectTx,
|
|
1175
|
-
status: tx.status,
|
|
1176
|
-
creator: tx.creator,
|
|
1177
|
-
createdAt: tx.createdAt,
|
|
1178
|
-
sequenceNumber: tx.sequenceNumber,
|
|
1179
|
-
votes: votes[i].map((vote) => ({
|
|
1180
|
-
userAddress: vote.userAddress,
|
|
1181
|
-
timestamp: vote.updatedAt
|
|
1182
|
-
}))
|
|
1183
|
-
}));
|
|
1184
|
-
}
|
|
1185
|
-
async getFutureIntentions(msafeAddress) {
|
|
1186
|
-
const currentSequenceNumber = await this.getCurrentSequenceNumber(msafeAddress);
|
|
1187
|
-
const hasPending = await this.model.pendingTransaction.findOneBy({ msafeAddress }) !== null;
|
|
1188
|
-
const futureSNStart = hasPending ? currentSequenceNumber + 1 : currentSequenceNumber;
|
|
1189
|
-
const futureTxs = await this.model.transactionIntention.find({
|
|
1190
|
-
where: { msafeAddress, sequenceNumber: (0, import_typeorm.MoreThanOrEqual)(futureSNStart) },
|
|
1191
|
-
order: { sequenceNumber: "asc" }
|
|
1192
|
-
});
|
|
1193
|
-
return futureTxs.map((tx) => ({
|
|
1194
|
-
intention: IntentionHelper.de(tx.data),
|
|
1195
|
-
msafeAddress: tx.msafeAddress,
|
|
1196
|
-
sequenceNumber: tx.sequenceNumber,
|
|
1197
|
-
rawData: tx.data,
|
|
1198
|
-
txType: tx.txType,
|
|
1199
|
-
txSubType: tx.txSubType,
|
|
1200
|
-
processed: tx.processed,
|
|
1201
|
-
status: tx.status,
|
|
1202
|
-
statusRemark: tx.statusRemark,
|
|
1203
|
-
creator: tx.creator,
|
|
1204
|
-
createdAt: tx.createdAt
|
|
1205
|
-
}));
|
|
1206
|
-
}
|
|
1207
|
-
async proposeIntention(input) {
|
|
1208
|
-
const userMSafe = await this.model.userMSafe.findOneBy({
|
|
1209
|
-
msafeAddress: input.msafeAddress,
|
|
1210
|
-
userAddress: input.userAddress
|
|
1211
|
-
});
|
|
1212
|
-
if (!userMSafe) {
|
|
1213
|
-
throw new Error("User does not have permission to propose intention");
|
|
1214
|
-
}
|
|
1215
|
-
const verified = await SignatureVerifier.verifyPersonalSignature({
|
|
1216
|
-
messageStr: MessageHelper.proposeIntentionMessage({ intention: input.intention, sn: input.sequenceNumber }),
|
|
1217
|
-
signature: input.signature,
|
|
1218
|
-
targetAddress: input.userAddress
|
|
1219
|
-
});
|
|
1220
|
-
if (!verified) {
|
|
1221
|
-
throw new Error("Invalid signature");
|
|
1222
|
-
}
|
|
1223
|
-
const sequenceNumber = await this.model.transactionIntention.count({
|
|
1224
|
-
where: {
|
|
1225
|
-
msafeAddress: input.msafeAddress
|
|
1226
|
-
}
|
|
1227
|
-
});
|
|
1228
|
-
if (sequenceNumber !== input.sequenceNumber) {
|
|
1229
|
-
throw new Error("Sequence number not expected");
|
|
1230
|
-
}
|
|
1231
|
-
const intention = {
|
|
1232
|
-
msafeAddress: input.msafeAddress,
|
|
1233
|
-
sequenceNumber,
|
|
1234
|
-
processed: false,
|
|
1235
|
-
...IntentionHelper.getTxType(input.intention),
|
|
1236
|
-
data: IntentionHelper.ser(input.intention),
|
|
1237
|
-
status: "NEW",
|
|
1238
|
-
creator: input.userAddress
|
|
1239
|
-
};
|
|
1240
|
-
await this.model.transactionIntention.save(intention);
|
|
1241
|
-
}
|
|
1242
|
-
// Propose a pending transaction. Require the msafe account
|
|
1243
|
-
// Does not have any pending transactions.
|
|
1244
|
-
async proposePendingTransaction(input) {
|
|
1245
|
-
const userMSafe = await this.model.userMSafe.findOneBy({
|
|
1246
|
-
msafeAddress: input.msafeAddress,
|
|
1247
|
-
userAddress: input.userAddress
|
|
1248
|
-
});
|
|
1249
|
-
if (userMSafe === null) {
|
|
1250
|
-
throw new Error("Unauthorized");
|
|
1251
|
-
}
|
|
1252
|
-
const msafePendings = await this.model.pendingTransaction.findBy({
|
|
1253
|
-
msafeAddress: input.msafeAddress
|
|
1254
|
-
});
|
|
1255
|
-
if (msafePendings.length !== 0) {
|
|
1256
|
-
throw new Error("Still have pending transaction");
|
|
1257
|
-
}
|
|
1258
|
-
const txb = await IntentionHelper.buildTxb({
|
|
1259
|
-
suiClient: this._suiClient,
|
|
1260
|
-
intention: input.intention,
|
|
1261
|
-
sender: input.msafeAddress
|
|
1262
|
-
});
|
|
1263
|
-
const payload = await txb.build({ client: this._suiClient });
|
|
1264
|
-
const txDigest = await txb.getDigest({ client: this._suiClient });
|
|
1265
|
-
if (txDigest !== input.digest) {
|
|
1266
|
-
throw new Error("Transaction digest un-match");
|
|
1267
|
-
}
|
|
1268
|
-
const verified = await SignatureVerifier.verifyTransactionSignature({
|
|
1269
|
-
payload,
|
|
1270
|
-
targetAddress: input.userAddress,
|
|
1271
|
-
signature: input.signature
|
|
1272
|
-
});
|
|
1273
|
-
if (!verified) {
|
|
1274
|
-
throw new Error("Failed to verify signature");
|
|
1275
|
-
}
|
|
1276
|
-
const maxSNHistory = await this.model.historyTransaction.findOne({
|
|
1277
|
-
where: { msafeAddress: input.msafeAddress },
|
|
1278
|
-
order: { sequenceNumber: "desc" }
|
|
1279
|
-
});
|
|
1280
|
-
const sequenceNumber = maxSNHistory === null ? 0 : maxSNHistory.sequenceNumber + 1;
|
|
1281
|
-
const intention = {
|
|
1282
|
-
msafeAddress: input.msafeAddress,
|
|
1283
|
-
sequenceNumber,
|
|
1284
|
-
processed: false,
|
|
1285
|
-
...IntentionHelper.getTxType(input.intention),
|
|
1286
|
-
data: IntentionHelper.ser(input.intention),
|
|
1287
|
-
status: "SUCCESS",
|
|
1288
|
-
creator: input.userAddress
|
|
1289
|
-
};
|
|
1290
|
-
await this.model.transactionIntention.save(intention);
|
|
1291
|
-
const pendingTx = {
|
|
1292
|
-
digest: txDigest,
|
|
1293
|
-
msafeAddress: input.msafeAddress,
|
|
1294
|
-
payload: Uint8ArrayToHex(payload),
|
|
1295
|
-
sequenceNumber,
|
|
1296
|
-
isRejectTx: false,
|
|
1297
|
-
creator: input.userAddress
|
|
1298
|
-
};
|
|
1299
|
-
await this.model.pendingTransaction.save(pendingTx);
|
|
1300
|
-
const userVote = {
|
|
1301
|
-
userAddress: input.userAddress,
|
|
1302
|
-
txDigest,
|
|
1303
|
-
msafeAddress: input.msafeAddress,
|
|
1304
|
-
signature: input.signature,
|
|
1305
|
-
isValid: true
|
|
1306
|
-
};
|
|
1307
|
-
await this.model.userVote.save(userVote);
|
|
1308
|
-
}
|
|
1309
|
-
// Calls for the first reject transaction
|
|
1310
|
-
async rejectCurrentTx(input) {
|
|
1311
|
-
const userMSafe = await this.model.userMSafe.findOneBy({
|
|
1312
|
-
userAddress: input.userAddress,
|
|
1313
|
-
msafeAddress: input.msafeAddress
|
|
1314
|
-
});
|
|
1315
|
-
if (userMSafe === null) {
|
|
1316
|
-
throw new Error("User does not have permission to MSafe");
|
|
1317
|
-
}
|
|
1318
|
-
const currentPending = await this.model.pendingTransaction.findOneBy({
|
|
1319
|
-
msafeAddress: input.msafeAddress,
|
|
1320
|
-
isRejectTx: false
|
|
1321
|
-
});
|
|
1322
|
-
if (currentPending === null) {
|
|
1323
|
-
throw new Error("No active pending transaction");
|
|
1324
|
-
}
|
|
1325
|
-
const txb = await IntentionHelper.buildRejectTransaction({
|
|
1326
|
-
msafeAddress: input.msafeAddress,
|
|
1327
|
-
payloadToReject: currentPending.payload
|
|
1328
|
-
});
|
|
1329
|
-
const payload = await txb.build({ client: this._suiClient });
|
|
1330
|
-
const digest = await txb.getDigest({ client: this._suiClient });
|
|
1331
|
-
if (input.digest !== digest) {
|
|
1332
|
-
throw new Error("Digest not match");
|
|
1333
|
-
}
|
|
1334
|
-
const verified = await SignatureVerifier.verifyTransactionSignature({
|
|
1335
|
-
payload,
|
|
1336
|
-
targetAddress: input.userAddress,
|
|
1337
|
-
signature: input.signature
|
|
1338
|
-
});
|
|
1339
|
-
if (!verified) {
|
|
1340
|
-
throw new Error("Signature unverified");
|
|
1341
|
-
}
|
|
1342
|
-
const existPendingReject = await this.model.pendingTransaction.findOneBy({
|
|
1343
|
-
msafeAddress: input.msafeAddress,
|
|
1344
|
-
isRejectTx: true
|
|
1345
|
-
});
|
|
1346
|
-
if (existPendingReject !== null) {
|
|
1347
|
-
await this.voteForTransaction({
|
|
1348
|
-
txDigest: existPendingReject.digest,
|
|
1349
|
-
msafeAddress: input.msafeAddress,
|
|
1350
|
-
userAddress: input.userAddress,
|
|
1351
|
-
signature: input.signature
|
|
1352
|
-
});
|
|
1353
|
-
return;
|
|
1354
|
-
}
|
|
1355
|
-
const rejectPayloadStr = Uint8ArrayToHex(payload);
|
|
1356
|
-
const rejectDigest = await txb.getDigest({ client: this._suiClient });
|
|
1357
|
-
const rejectPending = {
|
|
1358
|
-
msafeAddress: input.msafeAddress,
|
|
1359
|
-
digest: rejectDigest,
|
|
1360
|
-
payload: rejectPayloadStr,
|
|
1361
|
-
sequenceNumber: currentPending.sequenceNumber,
|
|
1362
|
-
isRejectTx: true,
|
|
1363
|
-
creator: input.userAddress
|
|
1364
|
-
};
|
|
1365
|
-
await this.model.pendingTransaction.save(rejectPending);
|
|
1366
|
-
const rejectVote = {
|
|
1367
|
-
userAddress: input.userAddress,
|
|
1368
|
-
msafeAddress: input.msafeAddress,
|
|
1369
|
-
txDigest: rejectDigest,
|
|
1370
|
-
signature: input.signature,
|
|
1371
|
-
isValid: true
|
|
1372
|
-
};
|
|
1373
|
-
await this.model.userVote.save(rejectVote);
|
|
1374
|
-
const existVote = await this.model.userVote.findOneBy({
|
|
1375
|
-
txDigest: currentPending.digest,
|
|
1376
|
-
userAddress: input.userAddress
|
|
1377
|
-
});
|
|
1378
|
-
if (existVote !== null) {
|
|
1379
|
-
await this.model.userVote.update(
|
|
1380
|
-
{ userAddress: input.userAddress, txDigest: currentPending.digest },
|
|
1381
|
-
{ isValid: false }
|
|
1382
|
-
);
|
|
1383
|
-
}
|
|
1384
|
-
}
|
|
1385
|
-
async voteForTransaction(input) {
|
|
1386
|
-
const pendingTx = await this.model.pendingTransaction.findOneBy({ digest: input.txDigest });
|
|
1387
|
-
if (!pendingTx) {
|
|
1388
|
-
throw new Error(`Pending transaction not found: ${input.txDigest}`);
|
|
1389
|
-
}
|
|
1390
|
-
if (pendingTx.msafeAddress !== input.msafeAddress) {
|
|
1391
|
-
throw new Error("MSafe address not match");
|
|
1392
|
-
}
|
|
1393
|
-
const userMSafe = await this.model.userMSafe.findOneBy({
|
|
1394
|
-
userAddress: input.userAddress,
|
|
1395
|
-
msafeAddress: input.msafeAddress
|
|
1396
|
-
});
|
|
1397
|
-
if (userMSafe === null) {
|
|
1398
|
-
throw new Error(`User (${input.userAddress}) does not have permission on MSafe account (${input.msafeAddress})`);
|
|
1399
|
-
}
|
|
1400
|
-
const payload = HexToUint8Array(pendingTx.payload);
|
|
1401
|
-
const verified = await SignatureVerifier.verifyTransactionSignature({
|
|
1402
|
-
payload,
|
|
1403
|
-
targetAddress: input.userAddress,
|
|
1404
|
-
signature: input.signature
|
|
1405
|
-
});
|
|
1406
|
-
if (!verified) {
|
|
1407
|
-
throw new Error("Invalid signature");
|
|
1408
|
-
}
|
|
1409
|
-
const rejectPendingTx = await this.model.pendingTransaction.findOneBy({
|
|
1410
|
-
msafeAddress: input.msafeAddress,
|
|
1411
|
-
sequenceNumber: pendingTx.sequenceNumber,
|
|
1412
|
-
isRejectTx: !pendingTx.isRejectTx
|
|
1413
|
-
});
|
|
1414
|
-
if (rejectPendingTx !== null) {
|
|
1415
|
-
await this.model.userVote.update(
|
|
1416
|
-
{
|
|
1417
|
-
userAddress: input.userAddress,
|
|
1418
|
-
txDigest: rejectPendingTx.digest,
|
|
1419
|
-
isValid: true
|
|
1420
|
-
},
|
|
1421
|
-
{ isValid: false }
|
|
1422
|
-
);
|
|
1423
|
-
}
|
|
1424
|
-
const existVote = await this.model.userVote.exist({
|
|
1425
|
-
where: {
|
|
1426
|
-
txDigest: input.txDigest,
|
|
1427
|
-
userAddress: input.userAddress
|
|
1428
|
-
}
|
|
1429
|
-
});
|
|
1430
|
-
if (!existVote) {
|
|
1431
|
-
const userVote = {
|
|
1432
|
-
txDigest: input.txDigest,
|
|
1433
|
-
userAddress: input.userAddress,
|
|
1434
|
-
msafeAddress: input.msafeAddress,
|
|
1435
|
-
signature: input.signature,
|
|
1436
|
-
isValid: true
|
|
1437
|
-
};
|
|
1438
|
-
await this.model.userVote.save(userVote);
|
|
1439
|
-
} else {
|
|
1440
|
-
await this.model.userVote.update(
|
|
1441
|
-
{
|
|
1442
|
-
txDigest: input.txDigest,
|
|
1443
|
-
userAddress: input.userAddress
|
|
1444
|
-
},
|
|
1445
|
-
{ isValid: true }
|
|
1446
|
-
);
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
// Mock the process of an executed transaction
|
|
1450
|
-
// Here only the essential logic of transaction processing logic
|
|
1451
|
-
// is implemented. Need more transaction parsing from the fetcher
|
|
1452
|
-
// module.
|
|
1453
|
-
//
|
|
1454
|
-
// TODO: User queryRunner to make the transaction atomic.
|
|
1455
|
-
async processExecutedTransaction(digest) {
|
|
1456
|
-
const historyTx = await this.model.historyTransaction.findOneBy({ digest });
|
|
1457
|
-
if (historyTx) {
|
|
1458
|
-
return;
|
|
1459
|
-
}
|
|
1460
|
-
const pendingTx = await this.model.pendingTransaction.findOneBy({ digest });
|
|
1461
|
-
if (!pendingTx) {
|
|
1462
|
-
throw new Error("Transaction digest not found");
|
|
1463
|
-
}
|
|
1464
|
-
await this.model.transactionIntention.update(
|
|
1465
|
-
{ msafeAddress: pendingTx.msafeAddress, sequenceNumber: pendingTx.sequenceNumber },
|
|
1466
|
-
{ processed: true }
|
|
1467
|
-
);
|
|
1468
|
-
const pendings = await this.model.pendingTransaction.findBy({
|
|
1469
|
-
msafeAddress: pendingTx.msafeAddress,
|
|
1470
|
-
sequenceNumber: pendingTx.sequenceNumber
|
|
1471
|
-
});
|
|
1472
|
-
if (pendings.length === 0) {
|
|
1473
|
-
throw new Error("Pending transaction not found");
|
|
1474
|
-
}
|
|
1475
|
-
const executionResult = "success";
|
|
1476
|
-
for (let i = 0; i !== pendings.length; i++) {
|
|
1477
|
-
const pending = pendings[i];
|
|
1478
|
-
const history = {
|
|
1479
|
-
digest: pending.digest,
|
|
1480
|
-
payload: pending.payload,
|
|
1481
|
-
msafeAddress: pending.msafeAddress,
|
|
1482
|
-
sequenceNumber: pending.sequenceNumber,
|
|
1483
|
-
isRejectTx: pending.isRejectTx,
|
|
1484
|
-
creator: pending.creator,
|
|
1485
|
-
createdAt: pending.createdAt,
|
|
1486
|
-
// TODO: Fill in this field based on transaction processing result
|
|
1487
|
-
status: pending.digest === digest ? executionResult : "rejected"
|
|
1488
|
-
};
|
|
1489
|
-
await this.model.historyTransaction.save(history);
|
|
1490
|
-
await this.model.pendingTransaction.delete({ digest: pending.digest });
|
|
1491
|
-
}
|
|
1492
|
-
}
|
|
1493
|
-
/**
|
|
1494
|
-
* Build the next transaction intention, and add the built transaction to pendings.
|
|
1495
|
-
* @param input
|
|
1496
|
-
*/
|
|
1497
|
-
async buildNextIntentionAndAddToPending(input) {
|
|
1498
|
-
const maxSNHistory = await this.model.historyTransaction.findOne({
|
|
1499
|
-
where: { msafeAddress: input.msafeAddress },
|
|
1500
|
-
order: { sequenceNumber: "desc" }
|
|
1501
|
-
});
|
|
1502
|
-
const nextSequenceNumber = maxSNHistory ? maxSNHistory.sequenceNumber + 1 : 0;
|
|
1503
|
-
const currentPendings = await this.model.pendingTransaction.findBy({
|
|
1504
|
-
msafeAddress: input.msafeAddress
|
|
1505
|
-
});
|
|
1506
|
-
if (currentPendings.length !== 0) {
|
|
1507
|
-
throw new Error("Still have pendings");
|
|
1508
|
-
}
|
|
1509
|
-
const nextTx = await this.model.transactionIntention.findOneBy({
|
|
1510
|
-
msafeAddress: input.msafeAddress,
|
|
1511
|
-
sequenceNumber: nextSequenceNumber
|
|
1512
|
-
});
|
|
1513
|
-
if (nextTx === null) {
|
|
1514
|
-
throw new Error("No future intentions to build");
|
|
1515
|
-
}
|
|
1516
|
-
const nextIntention = IntentionHelper.de(nextTx.data);
|
|
1517
|
-
try {
|
|
1518
|
-
const newTxb = await IntentionHelper.buildTxb({
|
|
1519
|
-
suiClient: this._suiClient,
|
|
1520
|
-
sender: input.msafeAddress,
|
|
1521
|
-
intention: nextIntention
|
|
1522
|
-
});
|
|
1523
|
-
const payload = await newTxb.build({ client: this._suiClient });
|
|
1524
|
-
const newDigest = await newTxb.getDigest({ client: this._suiClient });
|
|
1525
|
-
const newPending = {
|
|
1526
|
-
digest: newDigest,
|
|
1527
|
-
payload: Uint8ArrayToHex(payload),
|
|
1528
|
-
msafeAddress: input.msafeAddress,
|
|
1529
|
-
sequenceNumber: nextTx.sequenceNumber,
|
|
1530
|
-
isRejectTx: false,
|
|
1531
|
-
creator: nextTx.creator
|
|
1532
|
-
};
|
|
1533
|
-
await this.model.pendingTransaction.save(newPending);
|
|
1534
|
-
await this.model.transactionIntention.update(
|
|
1535
|
-
{
|
|
1536
|
-
msafeAddress: input.msafeAddress,
|
|
1537
|
-
sequenceNumber: nextSequenceNumber
|
|
1538
|
-
},
|
|
1539
|
-
{
|
|
1540
|
-
status: "SUCCESS"
|
|
1541
|
-
}
|
|
1542
|
-
);
|
|
1543
|
-
} catch (e) {
|
|
1544
|
-
await this.model.transactionIntention.update(
|
|
1545
|
-
{
|
|
1546
|
-
msafeAddress: input.msafeAddress,
|
|
1547
|
-
sequenceNumber: nextSequenceNumber
|
|
1548
|
-
},
|
|
1549
|
-
{
|
|
1550
|
-
status: "FAILED",
|
|
1551
|
-
statusRemark: e.toString()
|
|
1552
|
-
}
|
|
1553
|
-
);
|
|
1554
|
-
throw new Error(`Intention build failed: {sequenceNumber: ${nextSequenceNumber}}`);
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
/**
|
|
1558
|
-
* Skip next failed transaction if build of the intention has been failed before.
|
|
1559
|
-
*/
|
|
1560
|
-
async skipNextFailedIntention(input) {
|
|
1561
|
-
const userMSafe = await this.model.userMSafe.findOneBy({
|
|
1562
|
-
msafeAddress: input.msafeAddress,
|
|
1563
|
-
userAddress: input.userAddress
|
|
1564
|
-
});
|
|
1565
|
-
if (userMSafe === null) {
|
|
1566
|
-
throw new Error("user does not have permission to MSafe");
|
|
1567
|
-
}
|
|
1568
|
-
const curSequenceNumber = await this.model.historyTransaction.findOne({
|
|
1569
|
-
where: { msafeAddress: input.msafeAddress },
|
|
1570
|
-
order: { sequenceNumber: "desc" }
|
|
1571
|
-
});
|
|
1572
|
-
const nextSequenceNumber = curSequenceNumber ? curSequenceNumber.sequenceNumber + 1 : 0;
|
|
1573
|
-
const failedIntention = await this.model.transactionIntention.findOneBy({
|
|
1574
|
-
msafeAddress: input.msafeAddress,
|
|
1575
|
-
sequenceNumber: nextSequenceNumber
|
|
1576
|
-
});
|
|
1577
|
-
if (failedIntention === null) {
|
|
1578
|
-
throw new Error("Next intention not found");
|
|
1579
|
-
}
|
|
1580
|
-
if (failedIntention.status !== "FAILED") {
|
|
1581
|
-
throw new Error("Next intention not failed");
|
|
1582
|
-
}
|
|
1583
|
-
const history = {
|
|
1584
|
-
msafeAddress: input.msafeAddress,
|
|
1585
|
-
digest: "0x0",
|
|
1586
|
-
// Special case for build has been failed,
|
|
1587
|
-
payload: "",
|
|
1588
|
-
sequenceNumber: nextSequenceNumber,
|
|
1589
|
-
creator: failedIntention.creator,
|
|
1590
|
-
isRejectTx: false,
|
|
1591
|
-
status: "build-failed"
|
|
1592
|
-
};
|
|
1593
|
-
await this.model.historyTransaction.save(history);
|
|
1594
|
-
await this.model.transactionIntention.update(
|
|
1595
|
-
{ msafeAddress: input.msafeAddress, sequenceNumber: nextSequenceNumber },
|
|
1596
|
-
{ processed: true }
|
|
1597
|
-
);
|
|
1598
|
-
}
|
|
1599
|
-
async getUser(address) {
|
|
1600
|
-
return this.model.user.findOneBy({ address });
|
|
1601
|
-
}
|
|
1602
|
-
get model() {
|
|
1603
|
-
return this.db.coreModel;
|
|
1604
|
-
}
|
|
1605
|
-
};
|
|
1606
|
-
|
|
1607
772
|
// src/globals/const.ts
|
|
1608
773
|
var MSafeEnv = /* @__PURE__ */ ((MSafeEnv3) => {
|
|
1609
774
|
MSafeEnv3["local"] = "local";
|
|
@@ -1638,6 +803,8 @@ var DEV_DATABASE_CONFIG = {
|
|
|
1638
803
|
};
|
|
1639
804
|
var TESTNET_RPC_URL = "https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD";
|
|
1640
805
|
var MAINNET_RPC_URL = "https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7";
|
|
806
|
+
var LOCAL_API_URL = "http://127.0.0.1:3000";
|
|
807
|
+
var DEV_API_URL = "http://13.56.226.148";
|
|
1641
808
|
var ENV_CONFIGS = /* @__PURE__ */ new Map([
|
|
1642
809
|
[
|
|
1643
810
|
"unit" /* unit */,
|
|
@@ -1645,7 +812,8 @@ var ENV_CONFIGS = /* @__PURE__ */ new Map([
|
|
|
1645
812
|
suiClient: {
|
|
1646
813
|
url: TESTNET_RPC_URL
|
|
1647
814
|
},
|
|
1648
|
-
backend:
|
|
815
|
+
backend: LOCAL_DATABASE_CONFIG,
|
|
816
|
+
apiURL: LOCAL_API_URL
|
|
1649
817
|
}
|
|
1650
818
|
],
|
|
1651
819
|
[
|
|
@@ -1654,7 +822,8 @@ var ENV_CONFIGS = /* @__PURE__ */ new Map([
|
|
|
1654
822
|
suiClient: {
|
|
1655
823
|
url: TESTNET_RPC_URL
|
|
1656
824
|
},
|
|
1657
|
-
backend: LOCAL_DATABASE_CONFIG
|
|
825
|
+
backend: LOCAL_DATABASE_CONFIG,
|
|
826
|
+
apiURL: LOCAL_API_URL
|
|
1658
827
|
}
|
|
1659
828
|
],
|
|
1660
829
|
[
|
|
@@ -1663,7 +832,8 @@ var ENV_CONFIGS = /* @__PURE__ */ new Map([
|
|
|
1663
832
|
suiClient: {
|
|
1664
833
|
url: TESTNET_RPC_URL
|
|
1665
834
|
},
|
|
1666
|
-
backend: DEV_DATABASE_CONFIG
|
|
835
|
+
backend: DEV_DATABASE_CONFIG,
|
|
836
|
+
apiURL: DEV_API_URL
|
|
1667
837
|
}
|
|
1668
838
|
]
|
|
1669
839
|
]);
|
|
@@ -1682,6 +852,140 @@ function getMSafeConfig(env, options) {
|
|
|
1682
852
|
}
|
|
1683
853
|
var AUTH_SIGN_MESSAGE = "Welcome to MSafe";
|
|
1684
854
|
|
|
855
|
+
// src/backend/BackendImpl.ts
|
|
856
|
+
var import_axios = __toESM(require("axios"), 1);
|
|
857
|
+
var BackendImpl = class {
|
|
858
|
+
constructor(apiURL) {
|
|
859
|
+
this.apiURL = apiURL;
|
|
860
|
+
}
|
|
861
|
+
_token;
|
|
862
|
+
async authSign(input) {
|
|
863
|
+
const res = await import_axios.default.post(`${this.apiURL}/auth/login`, input);
|
|
864
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
865
|
+
throw new Error(`invalid authSign return: ${res}`);
|
|
866
|
+
}
|
|
867
|
+
this._token = res.data.accessToken;
|
|
868
|
+
return this._token;
|
|
869
|
+
}
|
|
870
|
+
setJWTToken(token) {
|
|
871
|
+
this._token = token;
|
|
872
|
+
}
|
|
873
|
+
async getPublicKey(address) {
|
|
874
|
+
return (await this.getPublicKeyBatch([address]))[0];
|
|
875
|
+
}
|
|
876
|
+
async getPublicKeyBatch(addresses) {
|
|
877
|
+
const res = await import_axios.default.post(
|
|
878
|
+
`${this.apiURL}/account/getPublicKeyBatch`,
|
|
879
|
+
addresses,
|
|
880
|
+
{
|
|
881
|
+
headers: this.headers()
|
|
882
|
+
}
|
|
883
|
+
);
|
|
884
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
885
|
+
throw new Error(`invalid getPublicKeyBatch return: ${res}`);
|
|
886
|
+
}
|
|
887
|
+
return res.data?.map(
|
|
888
|
+
(publicKeyWithSchema) => publicKeyWithSchema ? PublicKeySerde.de({ ...publicKeyWithSchema }) : void 0
|
|
889
|
+
);
|
|
890
|
+
}
|
|
891
|
+
async getMSafeAccountInfo(msafeAddress) {
|
|
892
|
+
const res = await import_axios.default.get(
|
|
893
|
+
`${this.apiURL}/account/getMSafeAccountInfo/${msafeAddress}`,
|
|
894
|
+
{
|
|
895
|
+
headers: this.headers()
|
|
896
|
+
}
|
|
897
|
+
);
|
|
898
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
899
|
+
throw new Error(`invalid getPublicKeyBatch return: ${res}`);
|
|
900
|
+
}
|
|
901
|
+
const msafeResp = res.data;
|
|
902
|
+
return {
|
|
903
|
+
address: msafeResp.address,
|
|
904
|
+
ownersWithWeightPK: msafeResp.ownersWithWeightPKEncoded.map(
|
|
905
|
+
(owner) => ({
|
|
906
|
+
publicKey: PublicKeySerde.de({ publicKey: owner.publicKeyEncoded, scheme: owner.schema }),
|
|
907
|
+
address: owner.address,
|
|
908
|
+
weight: owner.weight
|
|
909
|
+
})
|
|
910
|
+
),
|
|
911
|
+
threshold: msafeResp.threshold,
|
|
912
|
+
name: msafeResp.name,
|
|
913
|
+
description: msafeResp.description,
|
|
914
|
+
creationNonce: msafeResp.creationNonce
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
async getUserInfo(userAddress) {
|
|
918
|
+
const res = await import_axios.default.get(`${this.apiURL}/account/user/${userAddress}`, {
|
|
919
|
+
headers: this.headers()
|
|
920
|
+
});
|
|
921
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
922
|
+
throw new Error(`invalid getPublicKeyBatch return: ${res}`);
|
|
923
|
+
}
|
|
924
|
+
return {
|
|
925
|
+
address: res.data.address,
|
|
926
|
+
publicKey: res.data.publicKey,
|
|
927
|
+
schema: res.data.schema,
|
|
928
|
+
creationNonce: res.data.creationNonce,
|
|
929
|
+
ownedMSafe: res.data.ownedMSafe.map(
|
|
930
|
+
(msafe) => ({
|
|
931
|
+
address: msafe.address,
|
|
932
|
+
ownersWithWeightPK: msafe.ownersWithWeightPKEncoded.map(
|
|
933
|
+
(owner) => ({
|
|
934
|
+
publicKey: PublicKeySerde.de({ publicKey: owner.publicKeyEncoded, scheme: owner.schema }),
|
|
935
|
+
address: owner.address,
|
|
936
|
+
weight: owner.weight
|
|
937
|
+
})
|
|
938
|
+
),
|
|
939
|
+
threshold: msafe.threshold,
|
|
940
|
+
name: msafe.name,
|
|
941
|
+
description: msafe.description,
|
|
942
|
+
creationNonce: msafe.creationNonce
|
|
943
|
+
})
|
|
944
|
+
)
|
|
945
|
+
};
|
|
946
|
+
}
|
|
947
|
+
async getPendingTransactions(msafeAddress) {
|
|
948
|
+
return [];
|
|
949
|
+
}
|
|
950
|
+
async getHistoryTransactions(msafeAddress) {
|
|
951
|
+
return [];
|
|
952
|
+
}
|
|
953
|
+
async getFutureIntentions(msafeAddress) {
|
|
954
|
+
return [];
|
|
955
|
+
}
|
|
956
|
+
async getCurrentSequenceNumber(msafeAddress) {
|
|
957
|
+
return 0;
|
|
958
|
+
}
|
|
959
|
+
async getNextSequenceNumber(msafeAddress) {
|
|
960
|
+
return 0;
|
|
961
|
+
}
|
|
962
|
+
async createMSafeAccount(input) {
|
|
963
|
+
const res = await import_axios.default.post(`${this.apiURL}/account`, input, {
|
|
964
|
+
headers: this.headers()
|
|
965
|
+
});
|
|
966
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
967
|
+
throw new Error(`invalid createMSafeAccount return: ${res}`);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
async proposeIntention(input) {
|
|
971
|
+
}
|
|
972
|
+
async proposePendingTransaction(input) {
|
|
973
|
+
}
|
|
974
|
+
async rejectCurrentTx(input) {
|
|
975
|
+
}
|
|
976
|
+
async voteForTransaction(input) {
|
|
977
|
+
}
|
|
978
|
+
async buildNextIntentionAndAddToPending(input) {
|
|
979
|
+
}
|
|
980
|
+
async skipNextFailedIntention(input) {
|
|
981
|
+
}
|
|
982
|
+
async processExecutedTransaction(digest) {
|
|
983
|
+
}
|
|
984
|
+
headers() {
|
|
985
|
+
return { Authorization: `Bearer ${this._token}` };
|
|
986
|
+
}
|
|
987
|
+
};
|
|
988
|
+
|
|
1685
989
|
// src/globals/MSafeGlobals.ts
|
|
1686
990
|
var MSafeGlobals = class _MSafeGlobals {
|
|
1687
991
|
backend;
|
|
@@ -1696,7 +1000,7 @@ var MSafeGlobals = class _MSafeGlobals {
|
|
|
1696
1000
|
static async New(env, options) {
|
|
1697
1001
|
const config = getMSafeConfig(env, options);
|
|
1698
1002
|
const suiClient = new import_client.SuiClient(config.suiClient);
|
|
1699
|
-
const backend =
|
|
1003
|
+
const backend = new BackendImpl(config.apiURL);
|
|
1700
1004
|
return new _MSafeGlobals({
|
|
1701
1005
|
backend,
|
|
1702
1006
|
suiClient,
|
|
@@ -1730,11 +1034,6 @@ var MSafeClient = class _MSafeClient {
|
|
|
1730
1034
|
}
|
|
1731
1035
|
async connectWallet(input) {
|
|
1732
1036
|
this.globals.wallet = input.wallet;
|
|
1733
|
-
const isValidJWT = input.jwtToken && await this.backend.isJWTTokenValid(input.jwtToken);
|
|
1734
|
-
if (isValidJWT) {
|
|
1735
|
-
this.backend.setJWTToken(input.jwtToken);
|
|
1736
|
-
return input.jwtToken;
|
|
1737
|
-
}
|
|
1738
1037
|
const messageStr = MessageHelper.welcomeMessage((/* @__PURE__ */ new Date()).toUTCString());
|
|
1739
1038
|
const sig = await input.wallet.signPersonalMessage({
|
|
1740
1039
|
messageStr
|
|
@@ -1793,28 +1092,21 @@ var MSafeClient = class _MSafeClient {
|
|
|
1793
1092
|
Coin,
|
|
1794
1093
|
CoinHelper,
|
|
1795
1094
|
CreateHelper,
|
|
1095
|
+
DEV_API_URL,
|
|
1796
1096
|
DEV_DATABASE_CONFIG,
|
|
1797
1097
|
ENV_CONFIGS,
|
|
1798
1098
|
Formatter,
|
|
1799
1099
|
HexToUint8Array,
|
|
1800
1100
|
IntentionHelper,
|
|
1101
|
+
LOCAL_API_URL,
|
|
1801
1102
|
LOCAL_DATABASE_CONFIG,
|
|
1802
1103
|
MAINNET_RPC_URL,
|
|
1803
|
-
MAX_OWNER_WITHOUT_NONCE,
|
|
1804
|
-
MAX_OWNER_WITH_NONCE,
|
|
1805
|
-
MAX_WEIGHT,
|
|
1806
|
-
MIN_THRESHOLD,
|
|
1807
|
-
MIN_WEIGHT,
|
|
1808
1104
|
MSafeAccount,
|
|
1809
1105
|
MSafeClient,
|
|
1810
1106
|
MSafeEnv,
|
|
1811
1107
|
MSafeGlobals,
|
|
1812
1108
|
MessageHelper,
|
|
1813
|
-
NONCE_PK_PREFIX,
|
|
1814
|
-
NONCE_PK_WEIGHT,
|
|
1815
|
-
NONCE_PREFIX_MAX_SIZE,
|
|
1816
1109
|
PublicKeySerde,
|
|
1817
|
-
RawMultiSig,
|
|
1818
1110
|
SUI_COIN,
|
|
1819
1111
|
SignatureVerifier,
|
|
1820
1112
|
TESTNET_RPC_URL,
|
|
@@ -1822,10 +1114,7 @@ var MSafeClient = class _MSafeClient {
|
|
|
1822
1114
|
Uint8ArrayToHex,
|
|
1823
1115
|
getAllCoins,
|
|
1824
1116
|
getMSafeConfig,
|
|
1825
|
-
getMultiSigPublicKey,
|
|
1826
1117
|
getPublicKeyFromChain,
|
|
1827
|
-
|
|
1828
|
-
stringToBuffer,
|
|
1829
|
-
validateMultiSigConfig
|
|
1118
|
+
stringToBuffer
|
|
1830
1119
|
});
|
|
1831
1120
|
//# sourceMappingURL=index.cjs.map
|