@msafe/sui3-sdk 0.0.4-pre-6732d98.0 → 0.0.4
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 +969 -258
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +89 -24
- package/dist/index.d.ts +89 -24
- package/dist/index.js +958 -251
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/backend/PseudoBackend.ts +14 -25
- package/src/backend/interface.ts +10 -10
- package/src/backend/types.ts +21 -0
- package/src/core/CreateHelper.ts +12 -22
- package/src/core/MSafeAccount.ts +5 -9
- package/src/core/MSafeClient.ts +6 -2
- package/src/globals/MSafeGlobals.ts +1 -2
- package/src/globals/const.ts +1 -8
- package/src/types/msafe.ts +20 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/multi-sig.ts +113 -0
- package/src/backend/BackendImpl.ts +0 -196
package/src/core/CreateHelper.ts
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createAccountCreationMessage,
|
|
3
|
-
MultisigAccountManager,
|
|
4
|
-
MultiSigConfig,
|
|
5
|
-
OwnerWithWeightPKEncoded,
|
|
6
|
-
validateCreateAccountRequest,
|
|
7
|
-
} from '@msafe/sui3-utils';
|
|
8
1
|
import { PublicKey, SerializedSignature } from '@mysten/sui.js/cryptography';
|
|
9
2
|
|
|
3
|
+
import { MessageHelper } from '@/core/MessageHelper';
|
|
10
4
|
import { PublicKeyHelper } from '@/core/PublicKeyHelper';
|
|
11
5
|
import { MSafeGlobals } from '@/globals/MSafeGlobals';
|
|
12
6
|
import { CreateMSafeAccountInfo, CreatePermissionInfo } from '@/types/creation';
|
|
13
|
-
import {
|
|
7
|
+
import { MultiSigConfig, RawMultiSig, validateMultiSigConfig } from '@/utils/multi-sig';
|
|
14
8
|
|
|
15
9
|
export class CreateHelper {
|
|
16
10
|
constructor(
|
|
@@ -24,14 +18,14 @@ export class CreateHelper {
|
|
|
24
18
|
|
|
25
19
|
async calculateMSafeAddress(info: CreatePermissionInfo) {
|
|
26
20
|
const msConfig = await this.reduceCreationInfoToRawConfig(info);
|
|
27
|
-
const ms = new
|
|
28
|
-
return ms.
|
|
21
|
+
const ms = new RawMultiSig(msConfig);
|
|
22
|
+
return ms.suiAddress;
|
|
29
23
|
}
|
|
30
24
|
|
|
31
25
|
// Validate the create info and return the msafe address.
|
|
32
26
|
async validateCreateInfo(createInfo: CreateMSafeAccountInfo) {
|
|
33
27
|
const rawConfig = await this.reduceCreationInfoToRawConfig(createInfo);
|
|
34
|
-
|
|
28
|
+
validateMultiSigConfig(rawConfig);
|
|
35
29
|
|
|
36
30
|
// Calculate the sui address will check the multi-sig
|
|
37
31
|
return this.calculateMSafeAddress(createInfo);
|
|
@@ -40,7 +34,7 @@ export class CreateHelper {
|
|
|
40
34
|
async submitMSafeCreation(creationInfo: CreateMSafeAccountInfo) {
|
|
41
35
|
const msafeAddress = await this.validateCreateInfo(creationInfo);
|
|
42
36
|
|
|
43
|
-
const signingMessage =
|
|
37
|
+
const signingMessage = MessageHelper.createMSafeMessage(msafeAddress);
|
|
44
38
|
const signature = await this.globals.wallet.signPersonalMessage({ messageStr: signingMessage });
|
|
45
39
|
|
|
46
40
|
await this.submitToBackend(creationInfo, signature.signature);
|
|
@@ -56,7 +50,7 @@ export class CreateHelper {
|
|
|
56
50
|
});
|
|
57
51
|
return {
|
|
58
52
|
threshold: info.threshold,
|
|
59
|
-
|
|
53
|
+
ownerWithWeight: info.ownerWithWeight.map((owner, i) => ({
|
|
60
54
|
publicKey: publicKeys[i] as PublicKey,
|
|
61
55
|
weight: owner.weight,
|
|
62
56
|
})),
|
|
@@ -67,15 +61,11 @@ export class CreateHelper {
|
|
|
67
61
|
private async submitToBackend(createInfo: CreateMSafeAccountInfo, signature: SerializedSignature) {
|
|
68
62
|
const pks = await this.pkHelper.getPublicKeyBatch(createInfo.ownerWithWeight.map((owner) => owner.address));
|
|
69
63
|
await this.globals.backend.createMSafeAccount({
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
publicKeyEncoded: publicKeySer.publicKey,
|
|
76
|
-
schema: publicKeySer.scheme,
|
|
77
|
-
};
|
|
78
|
-
}),
|
|
64
|
+
ownerWithWeight: createInfo.ownerWithWeight.map((owner, i) => ({
|
|
65
|
+
address: owner.address,
|
|
66
|
+
weight: owner.weight,
|
|
67
|
+
publicKey: pks[i] as PublicKey, // PublicKey has been verified.
|
|
68
|
+
})),
|
|
79
69
|
threshold: createInfo.threshold,
|
|
80
70
|
name: createInfo.name, // name validation is deferred to backend
|
|
81
71
|
description: createInfo.description, // description validation is deferred to backend
|
package/src/core/MSafeAccount.ts
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
import { MSafeAccountInfo, MultisigAccountManager } from "@msafe/sui3-utils";
|
|
2
1
|
import { SerializedSignature } from '@mysten/sui.js/cryptography';
|
|
3
2
|
|
|
4
3
|
import { MessageHelper } from '@/core/MessageHelper';
|
|
5
4
|
import { MSafeGlobals } from '@/globals/MSafeGlobals';
|
|
6
5
|
import { IntentionHelper, TxIntention } from '@/transactions/intention';
|
|
7
|
-
import { PendingTx } from '@/types/msafe';
|
|
6
|
+
import { MSafeAccountInfo, PendingTx } from '@/types/msafe';
|
|
8
7
|
import { HexToUint8Array } from '@/utils/buffer';
|
|
8
|
+
import { RawMultiSig } from '@/utils/multi-sig';
|
|
9
9
|
|
|
10
10
|
export class MSafeAccount {
|
|
11
|
-
public
|
|
11
|
+
public rawMultiSig: RawMultiSig;
|
|
12
12
|
|
|
13
13
|
constructor(
|
|
14
14
|
public readonly globals: MSafeGlobals,
|
|
15
15
|
public readonly info: MSafeAccountInfo,
|
|
16
16
|
) {
|
|
17
|
-
this.
|
|
18
|
-
threshold: info.threshold,
|
|
19
|
-
ownersWithWeight: info.ownersWithWeightPK,
|
|
20
|
-
creationNonce: info.creationNonce,
|
|
21
|
-
});
|
|
17
|
+
this.rawMultiSig = RawMultiSig.fromMSafeAccountInfo(info);
|
|
22
18
|
}
|
|
23
19
|
|
|
24
20
|
static async new(globals: MSafeGlobals, address: string) {
|
|
@@ -141,7 +137,7 @@ export class MSafeAccount {
|
|
|
141
137
|
sigs.push(signature);
|
|
142
138
|
}
|
|
143
139
|
}
|
|
144
|
-
const multiSignature = this.
|
|
140
|
+
const multiSignature = this.rawMultiSig.combinePartialSignatures(sigs);
|
|
145
141
|
return this.suiClient.executeTransactionBlock({
|
|
146
142
|
transactionBlock: HexToUint8Array(pending.payload),
|
|
147
143
|
signature: multiSignature,
|
package/src/core/MSafeClient.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { MSafeAccountInfo } from '@msafe/sui3-utils';
|
|
2
|
-
|
|
3
1
|
import { JWTToken } from '@/backend/types';
|
|
4
2
|
import { CreateHelper } from '@/core/CreateHelper';
|
|
5
3
|
import { MessageHelper } from '@/core/MessageHelper';
|
|
@@ -8,6 +6,7 @@ import { PublicKeyHelper } from '@/core/PublicKeyHelper';
|
|
|
8
6
|
import { MSafeConfigOptions, MSafeEnv } from '@/globals/const';
|
|
9
7
|
import { MSafeGlobals } from '@/globals/MSafeGlobals';
|
|
10
8
|
import { CreateMSafeAccountInfo } from '@/types/creation';
|
|
9
|
+
import { MSafeAccountInfo } from '@/types/msafe';
|
|
11
10
|
import { IWallet } from '@/types/wallet';
|
|
12
11
|
|
|
13
12
|
export class MSafeClient {
|
|
@@ -24,6 +23,11 @@ export class MSafeClient {
|
|
|
24
23
|
|
|
25
24
|
async connectWallet(input: { wallet: IWallet; jwtToken?: JWTToken }): Promise<JWTToken> {
|
|
26
25
|
this.globals.wallet = input.wallet;
|
|
26
|
+
const isValidJWT = input.jwtToken && (await this.backend.isJWTTokenValid(input.jwtToken));
|
|
27
|
+
if (isValidJWT) {
|
|
28
|
+
this.backend.setJWTToken(input.jwtToken as JWTToken);
|
|
29
|
+
return input.jwtToken as JWTToken;
|
|
30
|
+
}
|
|
27
31
|
const messageStr = MessageHelper.welcomeMessage(new Date().toUTCString());
|
|
28
32
|
const sig = await input.wallet.signPersonalMessage({
|
|
29
33
|
messageStr,
|
|
@@ -4,7 +4,6 @@ import { IBackend } from '@/backend/interface';
|
|
|
4
4
|
import { PseudoBackend } from '@/backend/PseudoBackend';
|
|
5
5
|
import { getMSafeConfig, MSafeConfig, MSafeConfigOptions, MSafeEnv } from '@/globals/const';
|
|
6
6
|
import { IWallet } from '@/types/wallet';
|
|
7
|
-
import { BackendImpl } from "@/backend/BackendImpl";
|
|
8
7
|
|
|
9
8
|
export class MSafeGlobals {
|
|
10
9
|
public readonly backend: IBackend;
|
|
@@ -24,7 +23,7 @@ export class MSafeGlobals {
|
|
|
24
23
|
static async New(env: MSafeEnv, options?: MSafeConfigOptions) {
|
|
25
24
|
const config = getMSafeConfig(env, options);
|
|
26
25
|
const suiClient = new SuiClient(config.suiClient);
|
|
27
|
-
const backend =
|
|
26
|
+
const backend = await PseudoBackend.New(config.backend, suiClient);
|
|
28
27
|
return new MSafeGlobals({
|
|
29
28
|
backend,
|
|
30
29
|
suiClient,
|
package/src/globals/const.ts
CHANGED
|
@@ -13,7 +13,6 @@ export interface MSafeConfig {
|
|
|
13
13
|
url: string;
|
|
14
14
|
};
|
|
15
15
|
backend: DBConfig;
|
|
16
|
-
apiURL: string;
|
|
17
16
|
}
|
|
18
17
|
|
|
19
18
|
export interface MSafeConfigOptions {
|
|
@@ -55,9 +54,6 @@ export const DEV_DATABASE_CONFIG: DBConfig = {
|
|
|
55
54
|
export const TESTNET_RPC_URL = 'https://sui-testnet.blockvision.org/v1/2Sgk89ivT64MnKdcGzjmyjY2ndD';
|
|
56
55
|
export const MAINNET_RPC_URL = 'https://sui-mainnet.blockvision.org/v1/2Sgk7NPvqkd7mESYkxF01yX15l7';
|
|
57
56
|
|
|
58
|
-
export const LOCAL_API_URL = 'http://127.0.0.1:3000';
|
|
59
|
-
export const DEV_API_URL = 'http://13.56.226.148';
|
|
60
|
-
|
|
61
57
|
export const ENV_CONFIGS = new Map<MSafeEnv, MSafeConfig>([
|
|
62
58
|
[
|
|
63
59
|
MSafeEnv.unit,
|
|
@@ -65,8 +61,7 @@ export const ENV_CONFIGS = new Map<MSafeEnv, MSafeConfig>([
|
|
|
65
61
|
suiClient: {
|
|
66
62
|
url: TESTNET_RPC_URL,
|
|
67
63
|
},
|
|
68
|
-
backend:
|
|
69
|
-
apiURL: LOCAL_API_URL,
|
|
64
|
+
backend: UNIT_DATABASE_CONFIG,
|
|
70
65
|
},
|
|
71
66
|
],
|
|
72
67
|
[
|
|
@@ -76,7 +71,6 @@ export const ENV_CONFIGS = new Map<MSafeEnv, MSafeConfig>([
|
|
|
76
71
|
url: TESTNET_RPC_URL,
|
|
77
72
|
},
|
|
78
73
|
backend: LOCAL_DATABASE_CONFIG,
|
|
79
|
-
apiURL: LOCAL_API_URL,
|
|
80
74
|
},
|
|
81
75
|
],
|
|
82
76
|
[
|
|
@@ -86,7 +80,6 @@ export const ENV_CONFIGS = new Map<MSafeEnv, MSafeConfig>([
|
|
|
86
80
|
url: TESTNET_RPC_URL,
|
|
87
81
|
},
|
|
88
82
|
backend: DEV_DATABASE_CONFIG,
|
|
89
|
-
apiURL: DEV_API_URL,
|
|
90
83
|
},
|
|
91
84
|
],
|
|
92
85
|
]);
|
package/src/types/msafe.ts
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
|
+
import { PublicKey } from '@mysten/sui.js/src/cryptography';
|
|
2
|
+
|
|
1
3
|
import { TxIntention } from '@/transactions/intention';
|
|
2
4
|
|
|
5
|
+
export interface MSafeAccountInfo {
|
|
6
|
+
address: string;
|
|
7
|
+
ownersWithWeightPK: OwnerWithWeightPK[];
|
|
8
|
+
threshold: number;
|
|
9
|
+
name: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
creationNonce: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type OwnerWithWeightPK = OwnerWithWeight & {
|
|
15
|
+
publicKey: PublicKey;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export interface OwnerWithWeight {
|
|
19
|
+
address: string;
|
|
20
|
+
weight: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
3
23
|
export interface PendingTx {
|
|
4
24
|
digest: string;
|
|
5
25
|
payload: string;
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { PublicKey, SerializedSignature } from '@mysten/sui.js/cryptography';
|
|
2
|
+
import { Ed25519PublicKey } from '@mysten/sui.js/keypairs/ed25519';
|
|
3
|
+
import { MultiSigPublicKey } from '@mysten/sui.js/multisig';
|
|
4
|
+
|
|
5
|
+
import { MSafeAccountInfo } from '@/types/msafe';
|
|
6
|
+
import { stringToBuffer } from '@/utils/buffer';
|
|
7
|
+
|
|
8
|
+
export interface PublicKeyWithWeight {
|
|
9
|
+
publicKey: PublicKey;
|
|
10
|
+
weight: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface MultiSigConfig {
|
|
14
|
+
threshold: number;
|
|
15
|
+
ownerWithWeight: PublicKeyWithWeight[];
|
|
16
|
+
creationNonce: number | undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const NONCE_PK_PREFIX = 'maven';
|
|
20
|
+
export const NONCE_PREFIX_MAX_SIZE = 16;
|
|
21
|
+
export const NONCE_PK_WEIGHT = 1;
|
|
22
|
+
|
|
23
|
+
export const MAX_WEIGHT = 255;
|
|
24
|
+
export const MIN_WEIGHT = 1;
|
|
25
|
+
export const MAX_OWNER_WITH_NONCE = 9;
|
|
26
|
+
export const MAX_OWNER_WITHOUT_NONCE = 10;
|
|
27
|
+
export const MIN_THRESHOLD = 1;
|
|
28
|
+
|
|
29
|
+
export class RawMultiSig {
|
|
30
|
+
rawMsPK: MultiSigPublicKey;
|
|
31
|
+
|
|
32
|
+
constructor(public readonly config: MultiSigConfig) {
|
|
33
|
+
this.rawMsPK = getMultiSigPublicKey(config);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static fromMSafeAccountInfo(info: MSafeAccountInfo) {
|
|
37
|
+
const parsed: MultiSigConfig = {
|
|
38
|
+
threshold: info.threshold,
|
|
39
|
+
ownerWithWeight: info.ownersWithWeightPK,
|
|
40
|
+
creationNonce: info.creationNonce,
|
|
41
|
+
};
|
|
42
|
+
return new RawMultiSig(parsed);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get suiAddress(): string {
|
|
46
|
+
return this.rawMsPK.toSuiAddress();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get publicKeys(): PublicKeyWithWeight[] {
|
|
50
|
+
return this.rawMsPK.getPublicKeys();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
get threshold(): number {
|
|
54
|
+
return this.config.threshold;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
combinePartialSignatures(signatures: SerializedSignature[]): SerializedSignature {
|
|
58
|
+
return this.rawMsPK.combinePartialSignatures(signatures);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async verifyPersonalMessage(messageStr: string, multiSigSignature: SerializedSignature): Promise<boolean> {
|
|
62
|
+
const message = stringToBuffer(messageStr);
|
|
63
|
+
return this.rawMsPK.verifyPersonalMessage(message, multiSigSignature);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function getMultiSigPublicKey(config: MultiSigConfig) {
|
|
68
|
+
const { ownerWithWeight, threshold, creationNonce } = config;
|
|
69
|
+
const pks = ownerWithWeight.map((pk) => ({
|
|
70
|
+
publicKey: pk.publicKey,
|
|
71
|
+
weight: pk.weight,
|
|
72
|
+
}));
|
|
73
|
+
if (creationNonce !== undefined) {
|
|
74
|
+
pks.push({
|
|
75
|
+
publicKey: makeNoncePublicKey(creationNonce),
|
|
76
|
+
weight: NONCE_PK_WEIGHT,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return MultiSigPublicKey.fromPublicKeys({ threshold, publicKeys: pks });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function makeNoncePublicKey(nonce: number) {
|
|
83
|
+
const buffer = new ArrayBuffer(Ed25519PublicKey.SIZE);
|
|
84
|
+
const textEncoder = new TextEncoder();
|
|
85
|
+
textEncoder.encodeInto(NONCE_PK_PREFIX, new Uint8Array(buffer, 0, NONCE_PREFIX_MAX_SIZE));
|
|
86
|
+
const nonceView = new DataView(buffer, NONCE_PREFIX_MAX_SIZE, 4);
|
|
87
|
+
nonceView.setUint32(0, nonce, true);
|
|
88
|
+
return new Ed25519PublicKey(new Uint8Array(buffer));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function validateMultiSigConfig(config: MultiSigConfig) {
|
|
92
|
+
config.ownerWithWeight.forEach((pk) => {
|
|
93
|
+
const { weight } = pk;
|
|
94
|
+
if (weight < MIN_WEIGHT || weight > MAX_WEIGHT) {
|
|
95
|
+
throw new Error(`Invalid multi-sig weight: ${weight} (1-${MAX_WEIGHT})`);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
const totalWeight = config.ownerWithWeight.reduce((s, pk) => s + pk.weight, 0);
|
|
99
|
+
if (config.threshold > totalWeight) {
|
|
100
|
+
throw new Error('Threshold is larger than total weight');
|
|
101
|
+
}
|
|
102
|
+
if (config.threshold < MIN_THRESHOLD) {
|
|
103
|
+
throw new Error('Threshold is smaller than 1');
|
|
104
|
+
}
|
|
105
|
+
const maxOwner = config.creationNonce === undefined ? MAX_OWNER_WITHOUT_NONCE : MAX_OWNER_WITH_NONCE;
|
|
106
|
+
if (config.ownerWithWeight.length > maxOwner) {
|
|
107
|
+
throw new Error('Owner number bigger than upper cap');
|
|
108
|
+
}
|
|
109
|
+
const addressSet = new Set(config.ownerWithWeight.map((pk) => pk.publicKey.toSuiAddress()));
|
|
110
|
+
if (addressSet.size !== config.ownerWithWeight.length) {
|
|
111
|
+
throw new Error('Duplicate address detected');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AuthLoginRequest,
|
|
3
|
-
AuthLoginResponse,
|
|
4
|
-
CreateMSafeAccountInfoRequest,
|
|
5
|
-
GetMSafeAccountInfoResponse,
|
|
6
|
-
MSafeAccountInfo,
|
|
7
|
-
OwnerWithWeightPK,
|
|
8
|
-
PublicKeyWithScheme,
|
|
9
|
-
UserWithOwnedMSafe,
|
|
10
|
-
UserWithOwnedMSafeResponse,
|
|
11
|
-
} from '@msafe/sui3-utils';
|
|
12
|
-
import { SerializedSignature } from '@mysten/sui.js/cryptography';
|
|
13
|
-
import { PublicKey } from '@mysten/sui.js/src/cryptography';
|
|
14
|
-
import axios from 'axios';
|
|
15
|
-
|
|
16
|
-
import { IBackend } from '@/backend/interface';
|
|
17
|
-
import { JWTToken } from '@/backend/types';
|
|
18
|
-
import { TxIntention } from '@/transactions/intention';
|
|
19
|
-
import { FutureIntention, HistorySendTx, PendingTx } from '@/types/msafe';
|
|
20
|
-
import { PublicKeySerde } from '@/utils/crypto';
|
|
21
|
-
|
|
22
|
-
export class BackendImpl implements IBackend {
|
|
23
|
-
private _token: JWTToken;
|
|
24
|
-
|
|
25
|
-
constructor(private readonly apiURL: string) {}
|
|
26
|
-
|
|
27
|
-
async authSign(input: AuthLoginRequest): Promise<JWTToken> {
|
|
28
|
-
const res = await axios.post<AuthLoginResponse>(`${this.apiURL}/auth/login`, input);
|
|
29
|
-
// TODO unify response struct
|
|
30
|
-
if (res.status !== 200 && res.status !== 201) {
|
|
31
|
-
throw new Error(`invalid authSign return: ${res}`);
|
|
32
|
-
}
|
|
33
|
-
this._token = res.data.accessToken;
|
|
34
|
-
return this._token;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
setJWTToken(token: JWTToken) {
|
|
38
|
-
this._token = token;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async getPublicKey(address: string): Promise<PublicKey | undefined> {
|
|
42
|
-
return (await this.getPublicKeyBatch([address]))[0];
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async getPublicKeyBatch(addresses: string[]): Promise<(PublicKey | undefined)[]> {
|
|
46
|
-
const res = await axios.post<(PublicKeyWithScheme | undefined)[]>(
|
|
47
|
-
`${this.apiURL}/account/getPublicKeyBatch`,
|
|
48
|
-
addresses,
|
|
49
|
-
{
|
|
50
|
-
headers: this.headers(),
|
|
51
|
-
},
|
|
52
|
-
);
|
|
53
|
-
// TODO unify response struct
|
|
54
|
-
if (res.status !== 200 && res.status !== 201) {
|
|
55
|
-
throw new Error(`invalid getPublicKeyBatch return: ${res}`);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return res.data?.map((publicKeyWithSchema) =>
|
|
59
|
-
publicKeyWithSchema ? PublicKeySerde.de({ ...publicKeyWithSchema }) : undefined,
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async getMSafeAccountInfo(msafeAddress: string): Promise<MSafeAccountInfo> {
|
|
64
|
-
const res = await axios.get<GetMSafeAccountInfoResponse>(
|
|
65
|
-
`${this.apiURL}/account/getMSafeAccountInfo/${msafeAddress}`,
|
|
66
|
-
{
|
|
67
|
-
headers: this.headers(),
|
|
68
|
-
},
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
// TODO unify response struct
|
|
72
|
-
if (res.status !== 200 && res.status !== 201) {
|
|
73
|
-
throw new Error(`invalid getPublicKeyBatch return: ${res}`);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const msafeResp = res.data;
|
|
77
|
-
return {
|
|
78
|
-
address: msafeResp.address,
|
|
79
|
-
ownersWithWeightPK: msafeResp.ownersWithWeightPKEncoded.map(
|
|
80
|
-
(owner): OwnerWithWeightPK => ({
|
|
81
|
-
publicKey: PublicKeySerde.de({ publicKey: owner.publicKeyEncoded, scheme: owner.schema }),
|
|
82
|
-
address: owner.address,
|
|
83
|
-
weight: owner.weight,
|
|
84
|
-
}),
|
|
85
|
-
),
|
|
86
|
-
threshold: msafeResp.threshold,
|
|
87
|
-
name: msafeResp.name,
|
|
88
|
-
description: msafeResp.description,
|
|
89
|
-
creationNonce: msafeResp.creationNonce,
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async getUserInfo(userAddress: string): Promise<UserWithOwnedMSafe> {
|
|
94
|
-
const res = await axios.get<UserWithOwnedMSafeResponse>(`${this.apiURL}/account/user/${userAddress}`, {
|
|
95
|
-
headers: this.headers(),
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
// TODO unify response struct
|
|
99
|
-
if (res.status !== 200 && res.status !== 201) {
|
|
100
|
-
throw new Error(`invalid getPublicKeyBatch return: ${res}`);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return {
|
|
104
|
-
address: res.data.address,
|
|
105
|
-
publicKey: res.data.publicKey,
|
|
106
|
-
schema: res.data.schema,
|
|
107
|
-
creationNonce: res.data.creationNonce,
|
|
108
|
-
ownedMSafe: res.data.ownedMSafe.map(
|
|
109
|
-
(msafe): MSafeAccountInfo => ({
|
|
110
|
-
address: msafe.address,
|
|
111
|
-
ownersWithWeightPK: msafe.ownersWithWeightPKEncoded.map(
|
|
112
|
-
(owner): OwnerWithWeightPK => ({
|
|
113
|
-
publicKey: PublicKeySerde.de({ publicKey: owner.publicKeyEncoded, scheme: owner.schema }),
|
|
114
|
-
address: owner.address,
|
|
115
|
-
weight: owner.weight,
|
|
116
|
-
}),
|
|
117
|
-
),
|
|
118
|
-
threshold: msafe.threshold,
|
|
119
|
-
name: msafe.name,
|
|
120
|
-
description: msafe.description,
|
|
121
|
-
creationNonce: msafe.creationNonce,
|
|
122
|
-
}),
|
|
123
|
-
),
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async getPendingTransactions(msafeAddress: string): Promise<PendingTx[]> {
|
|
128
|
-
return [];
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
async getHistoryTransactions(msafeAddress: string): Promise<HistorySendTx[]> {
|
|
132
|
-
return [];
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
async getFutureIntentions(msafeAddress: string): Promise<FutureIntention[]> {
|
|
136
|
-
return [];
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
async getCurrentSequenceNumber(msafeAddress: string): Promise<number> {
|
|
140
|
-
return 0;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
async getNextSequenceNumber(msafeAddress: string): Promise<number> {
|
|
144
|
-
return 0;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
async createMSafeAccount(input: CreateMSafeAccountInfoRequest): Promise<void> {
|
|
148
|
-
const res = await axios.post(`${this.apiURL}/account`, input, {
|
|
149
|
-
headers: this.headers(),
|
|
150
|
-
});
|
|
151
|
-
if (res.status !== 200 && res.status !== 201) {
|
|
152
|
-
throw new Error(`invalid createMSafeAccount return: ${res}`);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
async proposeIntention(input: {
|
|
157
|
-
intention: TxIntention;
|
|
158
|
-
sequenceNumber: number;
|
|
159
|
-
userAddress: string;
|
|
160
|
-
msafeAddress: string;
|
|
161
|
-
signature: SerializedSignature;
|
|
162
|
-
}): Promise<void> {
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
async proposePendingTransaction(input: {
|
|
166
|
-
intention: TxIntention;
|
|
167
|
-
userAddress: string;
|
|
168
|
-
msafeAddress: string;
|
|
169
|
-
digest: string;
|
|
170
|
-
signature: SerializedSignature;
|
|
171
|
-
}): Promise<void> {}
|
|
172
|
-
|
|
173
|
-
async rejectCurrentTx(input: {
|
|
174
|
-
userAddress: string;
|
|
175
|
-
msafeAddress: string;
|
|
176
|
-
digest: string;
|
|
177
|
-
signature: SerializedSignature;
|
|
178
|
-
}) {}
|
|
179
|
-
|
|
180
|
-
async voteForTransaction(input: {
|
|
181
|
-
txDigest: string;
|
|
182
|
-
msafeAddress: string;
|
|
183
|
-
userAddress: string;
|
|
184
|
-
signature: SerializedSignature;
|
|
185
|
-
}) {}
|
|
186
|
-
|
|
187
|
-
async buildNextIntentionAndAddToPending(input: { msafeAddress: string }) {}
|
|
188
|
-
|
|
189
|
-
async skipNextFailedIntention(input: { msafeAddress: string; userAddress: string }) {}
|
|
190
|
-
|
|
191
|
-
async processExecutedTransaction(digest: string) {}
|
|
192
|
-
|
|
193
|
-
private headers() {
|
|
194
|
-
return { Authorization: `Bearer ${this._token}` };
|
|
195
|
-
}
|
|
196
|
-
}
|