@mysten/sui
Version:
Sui TypeScript API(Work in Progress)
93 lines (74 loc) • 2.3 kB
text/typescript
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
import { toB64 } from '@mysten/bcs';
import type { SignatureScheme } from '../cryptography/index.js';
import { Signer } from '../cryptography/index.js';
import type { MultiSigPublicKey } from './publickey.js';
export class MultiSigSigner extends Signer {
#pubkey: MultiSigPublicKey;
#signers: Signer[];
constructor(pubkey: MultiSigPublicKey, signers: Signer[] = []) {
super();
this.#pubkey = pubkey;
this.#signers = signers;
let uniqueKeys = new Set();
let combinedWeight = 0;
const weights = pubkey.getPublicKeys().map(({ weight, publicKey }) => ({
weight,
address: publicKey.toSuiAddress(),
}));
for (let signer of signers) {
const address = signer.toSuiAddress();
if (uniqueKeys.has(address)) {
throw new Error(`Can't create MultiSigSigner with duplicate signers`);
}
uniqueKeys.add(address);
const weight = weights.find((w) => w.address === address)?.weight;
if (!weight) {
throw new Error(`Signer ${address} is not part of the MultiSig public key`);
}
combinedWeight += weight;
}
if (combinedWeight < pubkey.getThreshold()) {
throw new Error(`Combined weight of signers is less than threshold`);
}
}
getKeyScheme(): SignatureScheme {
return 'MultiSig';
}
getPublicKey(): MultiSigPublicKey {
return this.#pubkey;
}
sign(_data: Uint8Array): never {
throw new Error(
'MultiSigSigner does not support signing directly. Use signTransaction or signPersonalMessage instead',
);
}
signData(_data: Uint8Array): never {
throw new Error(
'MultiSigSigner does not support signing directly. Use signTransaction or signPersonalMessage instead',
);
}
async signTransaction(bytes: Uint8Array) {
const signature = this.#pubkey.combinePartialSignatures(
await Promise.all(
this.#signers.map(async (signer) => (await signer.signTransaction(bytes)).signature),
),
);
return {
signature,
bytes: toB64(bytes),
};
}
async signPersonalMessage(bytes: Uint8Array) {
const signature = this.#pubkey.combinePartialSignatures(
await Promise.all(
this.#signers.map(async (signer) => (await signer.signPersonalMessage(bytes)).signature),
),
);
return {
signature,
bytes: toB64(bytes),
};
}
}