@openzeppelin/miden-multisig-client 0.15.0 → 0.16.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/README.md +25 -1
- package/dist/account/builder.d.ts +2 -1
- package/dist/account/builder.d.ts.map +1 -1
- package/dist/account/builder.js +1 -0
- package/dist/account/builder.js.map +1 -1
- package/dist/account/builder.test.js +2 -2
- package/dist/account/builder.test.js.map +1 -1
- package/dist/client.d.ts +9 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +5 -5
- package/dist/client.js.map +1 -1
- package/dist/client.test.js +46 -15
- package/dist/client.test.js.map +1 -1
- package/dist/connectivity.d.ts +38 -0
- package/dist/connectivity.d.ts.map +1 -0
- package/dist/connectivity.js +97 -0
- package/dist/connectivity.js.map +1 -0
- package/dist/connectivity.test.d.ts +2 -0
- package/dist/connectivity.test.d.ts.map +1 -0
- package/dist/connectivity.test.js +61 -0
- package/dist/connectivity.test.js.map +1 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/multisig.d.ts +68 -7
- package/dist/multisig.d.ts.map +1 -1
- package/dist/multisig.js +90 -18
- package/dist/multisig.js.map +1 -1
- package/dist/multisig.test.js +214 -79
- package/dist/multisig.test.js.map +1 -1
- package/dist/proposal/metadata.d.ts.map +1 -1
- package/dist/proposal/metadata.js +12 -0
- package/dist/proposal/metadata.js.map +1 -1
- package/dist/proposal/metadata.test.js +49 -0
- package/dist/proposal/metadata.test.js.map +1 -1
- package/dist/raw-client.d.ts +2 -2
- package/dist/raw-client.d.ts.map +1 -1
- package/dist/raw-client.js +14 -4
- package/dist/raw-client.js.map +1 -1
- package/dist/raw-client.test.js +25 -3
- package/dist/raw-client.test.js.map +1 -1
- package/dist/signers/miden-wallet.d.ts +44 -1
- package/dist/signers/miden-wallet.d.ts.map +1 -1
- package/dist/signers/miden-wallet.ecdsa-recovery.test.d.ts +2 -0
- package/dist/signers/miden-wallet.ecdsa-recovery.test.d.ts.map +1 -0
- package/dist/signers/miden-wallet.ecdsa-recovery.test.js +148 -0
- package/dist/signers/miden-wallet.ecdsa-recovery.test.js.map +1 -0
- package/dist/signers/miden-wallet.js +97 -6
- package/dist/signers/miden-wallet.js.map +1 -1
- package/dist/signers/miden-wallet.test.js +8 -13
- package/dist/signers/miden-wallet.test.js.map +1 -1
- package/dist/transaction/consumeNotes.d.ts +6 -2
- package/dist/transaction/consumeNotes.d.ts.map +1 -1
- package/dist/transaction/consumeNotes.js +0 -4
- package/dist/transaction/consumeNotes.js.map +1 -1
- package/dist/transaction/options.d.ts +3 -0
- package/dist/transaction/options.d.ts.map +1 -1
- package/dist/transaction/p2id.d.ts +20 -2
- package/dist/transaction/p2id.d.ts.map +1 -1
- package/dist/transaction/p2id.js +46 -3
- package/dist/transaction/p2id.js.map +1 -1
- package/dist/transaction/p2id.test.js +66 -6
- package/dist/transaction/p2id.test.js.map +1 -1
- package/dist/transaction/summary.d.ts +2 -1
- package/dist/transaction/summary.d.ts.map +1 -1
- package/dist/transaction/summary.js.map +1 -1
- package/dist/transaction/updateGuardian.d.ts +6 -2
- package/dist/transaction/updateGuardian.d.ts.map +1 -1
- package/dist/transaction/updateGuardian.js.map +1 -1
- package/dist/transaction/updateProcedureThreshold.d.ts +7 -2
- package/dist/transaction/updateProcedureThreshold.d.ts.map +1 -1
- package/dist/transaction/updateProcedureThreshold.js.map +1 -1
- package/dist/transaction/updateSigners.d.ts +7 -2
- package/dist/transaction/updateSigners.d.ts.map +1 -1
- package/dist/transaction/updateSigners.js.map +1 -1
- package/dist/transaction.d.ts +1 -1
- package/dist/transaction.d.ts.map +1 -1
- package/dist/transaction.js +1 -1
- package/dist/transaction.js.map +1 -1
- package/dist/types/proposal.d.ts +5 -0
- package/dist/types/proposal.d.ts.map +1 -1
- package/dist/types/proposal.js +3 -0
- package/dist/types/proposal.js.map +1 -1
- package/dist/utils/ecdsa.d.ts +17 -0
- package/dist/utils/ecdsa.d.ts.map +1 -1
- package/dist/utils/ecdsa.js +44 -1
- package/dist/utils/ecdsa.js.map +1 -1
- package/dist/utils/ecdsa.test.js +46 -0
- package/dist/utils/ecdsa.test.js.map +1 -1
- package/package.json +12 -3
- package/src/account/builder.test.ts +19 -11
- package/src/account/builder.ts +2 -1
- package/src/client.test.ts +67 -15
- package/src/client.ts +18 -10
- package/src/connectivity.test.ts +67 -0
- package/src/connectivity.ts +111 -0
- package/src/index.ts +20 -1
- package/src/multisig.test.ts +267 -80
- package/src/multisig.ts +109 -20
- package/src/proposal/metadata.test.ts +60 -0
- package/src/proposal/metadata.ts +14 -0
- package/src/raw-client.test.ts +41 -3
- package/src/raw-client.ts +15 -5
- package/src/signers/miden-wallet.ecdsa-recovery.test.ts +201 -0
- package/src/signers/miden-wallet.test.ts +11 -19
- package/src/signers/miden-wallet.ts +134 -7
- package/src/transaction/consumeNotes.ts +11 -1
- package/src/transaction/options.ts +4 -0
- package/src/transaction/p2id.test.ts +98 -8
- package/src/transaction/p2id.ts +64 -4
- package/src/transaction/summary.ts +12 -0
- package/src/transaction/updateGuardian.ts +11 -1
- package/src/transaction/updateProcedureThreshold.ts +13 -1
- package/src/transaction/updateSigners.ts +13 -1
- package/src/transaction.ts +3 -0
- package/src/types/proposal.ts +9 -0
- package/src/utils/ecdsa.test.ts +60 -0
- package/src/utils/ecdsa.ts +51 -1
- package/dist/account/masm/authLibraries.d.ts +0 -6
- package/dist/account/masm/authLibraries.d.ts.map +0 -1
- package/dist/account/masm/authLibraries.js +0 -17
- package/dist/account/masm/authLibraries.js.map +0 -1
- package/dist/multisig/proposal/execution.d.ts +0 -20
- package/dist/multisig/proposal/execution.d.ts.map +0 -1
- package/dist/multisig/proposal/execution.js +0 -166
- package/dist/multisig/proposal/execution.js.map +0 -1
- package/dist/multisig/proposal/parser.d.ts +0 -17
- package/dist/multisig/proposal/parser.d.ts.map +0 -1
- package/dist/multisig/proposal/parser.js +0 -147
- package/dist/multisig/proposal/parser.js.map +0 -1
package/src/transaction/p2id.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TransactionRequest, Word } from '@miden-sdk/miden-sdk';
|
|
1
|
+
import type { Account, TransactionRequest, Word } from '@miden-sdk/miden-sdk';
|
|
2
2
|
import {
|
|
3
3
|
AccountId,
|
|
4
4
|
FeltArray,
|
|
@@ -19,6 +19,38 @@ import {
|
|
|
19
19
|
import { randomWord } from '../utils/random.js';
|
|
20
20
|
import { normalizeHexWord } from '../utils/encoding.js';
|
|
21
21
|
import type { SignatureOptions } from './options.js';
|
|
22
|
+
import type { P2idNoteVisibility } from '../types/proposal.js';
|
|
23
|
+
|
|
24
|
+
export interface P2idTransactionOptions extends SignatureOptions {
|
|
25
|
+
/** Visibility of the created note. Defaults to `NoteType.Public`. */
|
|
26
|
+
noteType?: NoteType;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Parses the metadata wire value for a P2ID note visibility (issue #322).
|
|
31
|
+
* Absent => public, the only behavior before the field existed. An unknown
|
|
32
|
+
* value is rejected rather than silently rebuilt as a public note that could
|
|
33
|
+
* never match the signed tx_summary commitment.
|
|
34
|
+
*/
|
|
35
|
+
export function parseP2idNoteType(value: string | undefined): NoteType {
|
|
36
|
+
switch (value) {
|
|
37
|
+
case undefined:
|
|
38
|
+
case 'public':
|
|
39
|
+
return NoteType.Public;
|
|
40
|
+
case 'private':
|
|
41
|
+
return NoteType.Private;
|
|
42
|
+
default:
|
|
43
|
+
throw new Error(`unsupported metadata.noteType '${value}': expected 'public' or 'private'`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Maps a note type to its metadata wire value, omitting the default so
|
|
49
|
+
* public-note payloads keep the pre-#322 wire shape.
|
|
50
|
+
*/
|
|
51
|
+
export function p2idNoteTypeToMetadata(noteType: NoteType | undefined): P2idNoteVisibility | undefined {
|
|
52
|
+
return noteType === NoteType.Private ? 'private' : undefined;
|
|
53
|
+
}
|
|
22
54
|
|
|
23
55
|
export function deriveP2idSerialNumber(salt: Word): Word {
|
|
24
56
|
const zeroWord = WordType.fromHex(`0x${'00'.repeat(32)}`);
|
|
@@ -28,6 +60,32 @@ export function deriveP2idSerialNumber(salt: Word): Word {
|
|
|
28
60
|
]));
|
|
29
61
|
}
|
|
30
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Builds the fungible asset to transfer, sourcing the callback flag from the held asset.
|
|
65
|
+
*
|
|
66
|
+
* In Miden 0.15 the callback flag is part of the vault key, so rebuilding the asset from
|
|
67
|
+
* `faucet`/`amount` with the default flag would not match the held asset and the transfer
|
|
68
|
+
* would abort. When the faucet is absent the default flag is used, surfacing the
|
|
69
|
+
* missing-asset error during execution.
|
|
70
|
+
*/
|
|
71
|
+
function resolveFungibleAssetFromVault(
|
|
72
|
+
account: Account,
|
|
73
|
+
faucet: AccountId,
|
|
74
|
+
amount: bigint,
|
|
75
|
+
): FungibleAsset {
|
|
76
|
+
const faucetHex = faucet.toString();
|
|
77
|
+
const assetFromVault = account
|
|
78
|
+
.vault()
|
|
79
|
+
.fungibleAssets()
|
|
80
|
+
.find(asset => asset.faucetId().toString() === faucetHex);
|
|
81
|
+
|
|
82
|
+
if (!assetFromVault) {
|
|
83
|
+
return new FungibleAsset(faucet, amount);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return FungibleAsset.fromVaultKey(assetFromVault.vaultKey(), amount);
|
|
87
|
+
}
|
|
88
|
+
|
|
31
89
|
function buildP2idNote(
|
|
32
90
|
sender: AccountId,
|
|
33
91
|
recipient: AccountId,
|
|
@@ -61,7 +119,8 @@ export function buildP2idTransactionRequest(
|
|
|
61
119
|
recipientId: string,
|
|
62
120
|
faucetId: string,
|
|
63
121
|
amount: bigint,
|
|
64
|
-
|
|
122
|
+
account: Account,
|
|
123
|
+
options: P2idTransactionOptions = {},
|
|
65
124
|
): { request: TransactionRequest; salt: Word } {
|
|
66
125
|
const sender = AccountId.fromHex(senderId);
|
|
67
126
|
const recipient = AccountId.fromHex(recipientId);
|
|
@@ -69,14 +128,15 @@ export function buildP2idTransactionRequest(
|
|
|
69
128
|
|
|
70
129
|
const authSaltHex = options.salt ? options.salt.toHex() : randomWord().toHex();
|
|
71
130
|
|
|
72
|
-
const asset =
|
|
131
|
+
const asset = resolveFungibleAssetFromVault(account, faucet, amount);
|
|
132
|
+
|
|
73
133
|
const noteAssets = new NoteAssets([asset]);
|
|
74
134
|
|
|
75
135
|
const note = buildP2idNote(
|
|
76
136
|
sender,
|
|
77
137
|
recipient,
|
|
78
138
|
noteAssets,
|
|
79
|
-
NoteType.Public,
|
|
139
|
+
options.noteType ?? NoteType.Public,
|
|
80
140
|
authSaltHex,
|
|
81
141
|
);
|
|
82
142
|
|
|
@@ -7,6 +7,18 @@ import type {
|
|
|
7
7
|
import { AccountId } from '@miden-sdk/miden-sdk';
|
|
8
8
|
import { getRawMidenClient } from '../raw-client.js';
|
|
9
9
|
|
|
10
|
+
export function executeForSummary(
|
|
11
|
+
client: MidenClient,
|
|
12
|
+
accountId: string,
|
|
13
|
+
txRequest: TransactionRequest,
|
|
14
|
+
midenRpcEndpoint: string,
|
|
15
|
+
): Promise<TransactionSummary>;
|
|
16
|
+
export function executeForSummary(
|
|
17
|
+
client: WasmWebClient,
|
|
18
|
+
accountId: string,
|
|
19
|
+
txRequest: TransactionRequest,
|
|
20
|
+
midenRpcEndpoint?: string,
|
|
21
|
+
): Promise<TransactionSummary>;
|
|
10
22
|
export async function executeForSummary(
|
|
11
23
|
client: MidenClient | WasmWebClient,
|
|
12
24
|
accountId: string,
|
|
@@ -13,7 +13,7 @@ import { GUARDIAN_ECDSA_MASM, GUARDIAN_MASM } from '../account/masm/auth.js';
|
|
|
13
13
|
import { compileTxScript } from '../raw-client.js';
|
|
14
14
|
import { normalizeHexWord } from '../utils/encoding.js';
|
|
15
15
|
import { randomWord } from '../utils/random.js';
|
|
16
|
-
import type { SignatureOptions } from './options.js';
|
|
16
|
+
import type { MidenClientSignatureOptions, SignatureOptions } from './options.js';
|
|
17
17
|
import type { SignatureScheme } from '../types.js';
|
|
18
18
|
|
|
19
19
|
async function buildUpdateGuardianScript(
|
|
@@ -42,6 +42,16 @@ end
|
|
|
42
42
|
);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
export function buildUpdateGuardianTransactionRequest(
|
|
46
|
+
client: MidenClient,
|
|
47
|
+
newGuardianPubkey: string,
|
|
48
|
+
options: MidenClientSignatureOptions,
|
|
49
|
+
): Promise<{ request: TransactionRequest; salt: Word }>;
|
|
50
|
+
export function buildUpdateGuardianTransactionRequest(
|
|
51
|
+
client: WasmWebClient,
|
|
52
|
+
newGuardianPubkey: string,
|
|
53
|
+
options?: SignatureOptions,
|
|
54
|
+
): Promise<{ request: TransactionRequest; salt: Word }>;
|
|
45
55
|
export async function buildUpdateGuardianTransactionRequest(
|
|
46
56
|
client: MidenClient | WasmWebClient,
|
|
47
57
|
newGuardianPubkey: string,
|
|
@@ -18,7 +18,7 @@ import { getProcedureRoot, type ProcedureName } from '../procedures.js';
|
|
|
18
18
|
import { compileTxScript } from '../raw-client.js';
|
|
19
19
|
import { normalizeHexWord } from '../utils/encoding.js';
|
|
20
20
|
import { randomWord } from '../utils/random.js';
|
|
21
|
-
import type { SignatureOptions } from './options.js';
|
|
21
|
+
import type { MidenClientSignatureOptions, SignatureOptions } from './options.js';
|
|
22
22
|
import type { SignatureScheme } from '../types.js';
|
|
23
23
|
|
|
24
24
|
function buildProcedureThresholdFelts(procedure: ProcedureName, threshold: number): Felt[] {
|
|
@@ -76,6 +76,18 @@ end
|
|
|
76
76
|
);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
export function buildUpdateProcedureThresholdTransactionRequest(
|
|
80
|
+
client: MidenClient,
|
|
81
|
+
procedure: ProcedureName,
|
|
82
|
+
threshold: number,
|
|
83
|
+
options: MidenClientSignatureOptions,
|
|
84
|
+
): Promise<{ request: TransactionRequest; salt: Word; configHash: Word }>;
|
|
85
|
+
export function buildUpdateProcedureThresholdTransactionRequest(
|
|
86
|
+
client: WasmWebClient,
|
|
87
|
+
procedure: ProcedureName,
|
|
88
|
+
threshold: number,
|
|
89
|
+
options?: SignatureOptions,
|
|
90
|
+
): Promise<{ request: TransactionRequest; salt: Word; configHash: Word }>;
|
|
79
91
|
export async function buildUpdateProcedureThresholdTransactionRequest(
|
|
80
92
|
client: MidenClient | WasmWebClient,
|
|
81
93
|
procedure: ProcedureName,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
import { compileTxScript } from '../raw-client.js';
|
|
19
19
|
import { normalizeHexWord } from '../utils/encoding.js';
|
|
20
20
|
import { randomWord } from '../utils/random.js';
|
|
21
|
-
import type { SignatureOptions } from './options.js';
|
|
21
|
+
import type { MidenClientSignatureOptions, SignatureOptions } from './options.js';
|
|
22
22
|
import type { SignatureScheme } from '../types.js';
|
|
23
23
|
|
|
24
24
|
function buildMultisigConfigFelts(threshold: number, signerCommitments: string[]): Felt[] {
|
|
@@ -73,6 +73,18 @@ end
|
|
|
73
73
|
);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
export function buildUpdateSignersTransactionRequest(
|
|
77
|
+
client: MidenClient,
|
|
78
|
+
threshold: number,
|
|
79
|
+
signerCommitments: string[],
|
|
80
|
+
options: MidenClientSignatureOptions,
|
|
81
|
+
): Promise<{ request: TransactionRequest; salt: Word; configHash: Word }>;
|
|
82
|
+
export function buildUpdateSignersTransactionRequest(
|
|
83
|
+
client: WasmWebClient,
|
|
84
|
+
threshold: number,
|
|
85
|
+
signerCommitments: string[],
|
|
86
|
+
options?: SignatureOptions,
|
|
87
|
+
): Promise<{ request: TransactionRequest; salt: Word; configHash: Word }>;
|
|
76
88
|
export async function buildUpdateSignersTransactionRequest(
|
|
77
89
|
client: MidenClient | WasmWebClient,
|
|
78
90
|
threshold: number,
|
package/src/transaction.ts
CHANGED
|
@@ -4,6 +4,9 @@ export {
|
|
|
4
4
|
export { executeForSummary } from './transaction/summary.js';
|
|
5
5
|
export {
|
|
6
6
|
buildP2idTransactionRequest,
|
|
7
|
+
parseP2idNoteType,
|
|
8
|
+
p2idNoteTypeToMetadata,
|
|
9
|
+
type P2idTransactionOptions,
|
|
7
10
|
} from './transaction/p2id.js';
|
|
8
11
|
export {
|
|
9
12
|
buildUpdateGuardianTransactionRequest,
|
package/src/types/proposal.ts
CHANGED
|
@@ -82,11 +82,20 @@ export function isConsumeNotesV1(md: ConsumeNotesProposalMetadata): boolean {
|
|
|
82
82
|
return md.metadataVersion === undefined || md.metadataVersion === 1;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
/** Wire values for a P2ID note's visibility (issue #322). */
|
|
86
|
+
export type P2idNoteVisibility = 'public' | 'private';
|
|
87
|
+
|
|
88
|
+
export function isP2idNoteVisibility(value: string): value is P2idNoteVisibility {
|
|
89
|
+
return value === 'public' || value === 'private';
|
|
90
|
+
}
|
|
91
|
+
|
|
85
92
|
export interface P2IdProposalMetadata extends BaseProposalMetadata {
|
|
86
93
|
proposalType: 'p2id';
|
|
87
94
|
recipientId: string;
|
|
88
95
|
faucetId: string;
|
|
89
96
|
amount: string;
|
|
97
|
+
/** Visibility of the created note. Absent on the wire => 'public' (pre-#322 proposals). */
|
|
98
|
+
noteType?: P2idNoteVisibility;
|
|
90
99
|
}
|
|
91
100
|
|
|
92
101
|
export interface CustomProposalMetadata extends BaseProposalMetadata {
|
package/src/utils/ecdsa.test.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { secp256k1 } from '@noble/curves/secp256k1';
|
|
3
|
+
import { keccak_256 } from '@noble/hashes/sha3.js';
|
|
2
4
|
import { EcdsaFormat } from './ecdsa.js';
|
|
5
|
+
import { bytesToHex } from './encoding.js';
|
|
3
6
|
|
|
4
7
|
describe('EcdsaFormat', () => {
|
|
5
8
|
describe('normalizeRecoveryByte', () => {
|
|
@@ -84,6 +87,23 @@ describe('EcdsaFormat', () => {
|
|
|
84
87
|
});
|
|
85
88
|
});
|
|
86
89
|
|
|
90
|
+
describe('isValidPublicKeyPoint', () => {
|
|
91
|
+
// The secp256k1 generator point G, compressed — a known-valid point.
|
|
92
|
+
const G = '0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798';
|
|
93
|
+
|
|
94
|
+
it('accepts a valid compressed secp256k1 point', () => {
|
|
95
|
+
expect(EcdsaFormat.isValidPublicKeyPoint(G)).toBe(true);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('rejects a valid-length key whose x is off-curve', () => {
|
|
99
|
+
expect(EcdsaFormat.isValidPublicKeyPoint('0x02' + 'ff'.repeat(32))).toBe(false);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('rejects a valid-length key with a bad prefix byte', () => {
|
|
103
|
+
expect(EcdsaFormat.isValidPublicKeyPoint('0xff' + 'ab'.repeat(32))).toBe(false);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
87
107
|
describe('keccakDigestHex', () => {
|
|
88
108
|
it('should return 0x-prefixed hex of keccak-256 hash', () => {
|
|
89
109
|
const result = EcdsaFormat.keccakDigestHex(new Uint8Array(0));
|
|
@@ -101,4 +121,44 @@ describe('EcdsaFormat', () => {
|
|
|
101
121
|
expect(a).not.toBe(b);
|
|
102
122
|
});
|
|
103
123
|
});
|
|
124
|
+
|
|
125
|
+
describe('recoverCompressedPublicKeyHex', () => {
|
|
126
|
+
const privateKey = new Uint8Array(32).fill(0x11);
|
|
127
|
+
const message = new Uint8Array([9, 8, 7, 6, 5]);
|
|
128
|
+
|
|
129
|
+
function sign(priv: Uint8Array, msg: Uint8Array): Uint8Array {
|
|
130
|
+
const sig = secp256k1.sign(keccak_256(msg), priv);
|
|
131
|
+
const out = new Uint8Array(65);
|
|
132
|
+
out.set(sig.toCompactRawBytes(), 0); // r || s
|
|
133
|
+
out[64] = sig.recovery; // v
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
it('recovers the compressed public key that produced the signature', () => {
|
|
138
|
+
const expected = bytesToHex(secp256k1.getPublicKey(privateKey, true));
|
|
139
|
+
const recovered = EcdsaFormat.recoverCompressedPublicKeyHex(message, sign(privateKey, message));
|
|
140
|
+
expect(recovered).toBe(expected);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('accepts an Ethereum-style recovery byte (27/28)', () => {
|
|
144
|
+
const sig = sign(privateKey, message);
|
|
145
|
+
sig[64] += 27; // 0/1 -> 27/28
|
|
146
|
+
const expected = bytesToHex(secp256k1.getPublicKey(privateKey, true));
|
|
147
|
+
expect(EcdsaFormat.recoverCompressedPublicKeyHex(message, sig)).toBe(expected);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('throws when the signature is not 65 bytes', () => {
|
|
151
|
+
expect(() => EcdsaFormat.recoverCompressedPublicKeyHex(message, new Uint8Array(64))).toThrow(
|
|
152
|
+
/65-byte signature/,
|
|
153
|
+
);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('throws on an invalid recovery byte', () => {
|
|
157
|
+
const sig = sign(privateKey, message);
|
|
158
|
+
sig[64] = 5;
|
|
159
|
+
expect(() => EcdsaFormat.recoverCompressedPublicKeyHex(message, sig)).toThrow(
|
|
160
|
+
/recovery byte must be/,
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
104
164
|
});
|
package/src/utils/ecdsa.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { secp256k1 } from '@noble/curves/secp256k1';
|
|
1
2
|
import { keccak_256 } from '@noble/hashes/sha3.js';
|
|
2
|
-
import { ensureHexPrefix } from './encoding.js';
|
|
3
|
+
import { bytesToHex, ensureHexPrefix } from './encoding.js';
|
|
3
4
|
|
|
4
5
|
const ECDSA_SIGNATURE_BYTE_LENGTH = 64;
|
|
5
6
|
const ECDSA_SIGNATURE_WITH_RECOVERY_BYTE_LENGTH = 65;
|
|
@@ -50,6 +51,21 @@ export class EcdsaFormat {
|
|
|
50
51
|
return byteLength === 33 || byteLength === 65;
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Whether `publicKeyHex` decodes to a valid secp256k1 curve point (compressed
|
|
56
|
+
* 33-byte or uncompressed 65-byte). Unlike {@link EcdsaFormat.validatePublicKeyHex}
|
|
57
|
+
* this rejects well-formed-length but off-curve or bad-prefix keys, and does so
|
|
58
|
+
* without the Miden WASM SDK.
|
|
59
|
+
*/
|
|
60
|
+
static isValidPublicKeyPoint(publicKeyHex: string): boolean {
|
|
61
|
+
try {
|
|
62
|
+
secp256k1.ProjectivePoint.fromHex(ensureHexPrefix(publicKeyHex).slice(2));
|
|
63
|
+
return true;
|
|
64
|
+
} catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
53
69
|
static compressPublicKey(uncompressedHex: string): string {
|
|
54
70
|
const clean = ensureHexPrefix(uncompressedHex).slice(2);
|
|
55
71
|
const byteLength = clean.length / 2;
|
|
@@ -74,4 +90,38 @@ export class EcdsaFormat {
|
|
|
74
90
|
}
|
|
75
91
|
return hex;
|
|
76
92
|
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Recover the compressed (33-byte) secp256k1 public key that produced an
|
|
96
|
+
* `ecdsa_k256_keccak` signature over `messageBytes`.
|
|
97
|
+
*
|
|
98
|
+
* `messageBytes` is the raw word/message bytes (the digest is `keccak256` of
|
|
99
|
+
* these, matching the transaction kernel and {@link EcdsaFormat.keccakDigestHex}).
|
|
100
|
+
* `signature` must be the 65-byte `r||s||v` form; the recovery byte may be the
|
|
101
|
+
* canonical `0/1` or the Ethereum-style `27/28`.
|
|
102
|
+
*/
|
|
103
|
+
static recoverCompressedPublicKeyHex(messageBytes: Uint8Array, signature: Uint8Array): string {
|
|
104
|
+
if (signature.length !== ECDSA_SIGNATURE_WITH_RECOVERY_BYTE_LENGTH) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
`ECDSA public-key recovery requires a ${ECDSA_SIGNATURE_WITH_RECOVERY_BYTE_LENGTH}-byte signature (r||s||v), got ${signature.length}`,
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
let recoveryBit = signature[ECDSA_SIGNATURE_BYTE_LENGTH];
|
|
111
|
+
if (recoveryBit === 27 || recoveryBit === 28) {
|
|
112
|
+
recoveryBit -= 27;
|
|
113
|
+
}
|
|
114
|
+
if (recoveryBit !== 0 && recoveryBit !== 1) {
|
|
115
|
+
throw new Error(
|
|
116
|
+
`ECDSA recovery byte must be 0/1 (or 27/28), got ${signature[ECDSA_SIGNATURE_BYTE_LENGTH]}`,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const compact = signature.slice(0, ECDSA_SIGNATURE_BYTE_LENGTH);
|
|
121
|
+
const msgHash = keccak_256(messageBytes);
|
|
122
|
+
const recovered = secp256k1.Signature.fromCompact(compact)
|
|
123
|
+
.addRecoveryBit(recoveryBit)
|
|
124
|
+
.recoverPublicKey(msgHash);
|
|
125
|
+
return bytesToHex(recovered.toRawBytes(true));
|
|
126
|
+
}
|
|
77
127
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authLibraries.d.ts","sourceRoot":"","sources":["../../../src/account/masm/authLibraries.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,iBAAiB,CAMjE,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Upstream `miden-standards` guarded-multisig MASM library modules, in dependency order.
|
|
3
|
-
*
|
|
4
|
-
* These are linked into the code builder (for account-component compilation) or built as
|
|
5
|
-
* libraries (for transaction scripts) before referencing `miden::standards::auth::*`
|
|
6
|
-
* procedures. The guarded-multisig component is scheme-agnostic (the per-signer scheme
|
|
7
|
-
* lives in account storage), so there is a single closure — no Falcon/ECDSA split.
|
|
8
|
-
*/
|
|
9
|
-
import { AUTH_MOD_MASM, AUTH_SIGNATURE_MASM, AUTH_TX_POLICY_MASM, MULTISIG_MASM, GUARDIAN_MASM, } from './auth.js';
|
|
10
|
-
export const AUTH_LIBRARY_MODULES = [
|
|
11
|
-
{ namespace: 'miden::standards::auth', code: AUTH_MOD_MASM },
|
|
12
|
-
{ namespace: 'miden::standards::auth::signature', code: AUTH_SIGNATURE_MASM },
|
|
13
|
-
{ namespace: 'miden::standards::auth::tx_policy', code: AUTH_TX_POLICY_MASM },
|
|
14
|
-
{ namespace: 'miden::standards::auth::multisig', code: MULTISIG_MASM },
|
|
15
|
-
{ namespace: 'miden::standards::auth::guardian', code: GUARDIAN_MASM },
|
|
16
|
-
];
|
|
17
|
-
//# sourceMappingURL=authLibraries.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authLibraries.js","sourceRoot":"","sources":["../../../src/account/masm/authLibraries.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,aAAa,GACd,MAAM,WAAW,CAAC;AAOnB,MAAM,CAAC,MAAM,oBAAoB,GAAqC;IACpE,EAAE,SAAS,EAAE,wBAAwB,EAAE,IAAI,EAAE,aAAa,EAAE;IAC5D,EAAE,SAAS,EAAE,mCAAmC,EAAE,IAAI,EAAE,mBAAmB,EAAE;IAC7E,EAAE,SAAS,EAAE,mCAAmC,EAAE,IAAI,EAAE,mBAAmB,EAAE;IAC7E,EAAE,SAAS,EAAE,kCAAkC,EAAE,IAAI,EAAE,aAAa,EAAE;IACtE,EAAE,SAAS,EAAE,kCAAkC,EAAE,IAAI,EAAE,aAAa,EAAE;CACvE,CAAC"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { type GuardianHttpClient } from '@openzeppelin/guardian-client';
|
|
2
|
-
import type { MidenClient, TransactionProver, TransactionRequest } from '@miden-sdk/miden-sdk';
|
|
3
|
-
import type { ProposalType, TransactionProposal } from '../../types.js';
|
|
4
|
-
interface ExecuteProposalWorkflowParams {
|
|
5
|
-
proposal: TransactionProposal;
|
|
6
|
-
accountId: string;
|
|
7
|
-
threshold: number;
|
|
8
|
-
signerCommitments: string[];
|
|
9
|
-
guardianCommitment: string;
|
|
10
|
-
guardianPublicKey?: string;
|
|
11
|
-
signatureScheme: 'falcon' | 'ecdsa';
|
|
12
|
-
getEffectiveThreshold: (proposalType: ProposalType) => number;
|
|
13
|
-
guardian: GuardianHttpClient;
|
|
14
|
-
midenClient: MidenClient;
|
|
15
|
-
transactionProver?: TransactionProver | null;
|
|
16
|
-
}
|
|
17
|
-
export declare function executeProposalWorkflow(params: ExecuteProposalWorkflowParams): Promise<void>;
|
|
18
|
-
export declare function createTransactionProposalRequest(params: ExecuteProposalWorkflowParams): Promise<TransactionRequest>;
|
|
19
|
-
export {};
|
|
20
|
-
//# sourceMappingURL=execution.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../../src/multisig/proposal/execution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAC1F,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAQ9B,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AA2BxE,UAAU,6BAA6B;IACrC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,QAAQ,GAAG,OAAO,CAAC;IACpC,qBAAqB,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,MAAM,CAAC;IAC9D,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,WAAW,EAAE,WAAW,CAAC;IACzB,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAC9C;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,IAAI,CAAC,CA4Cf;AAGD,wBAAsB,gCAAgC,CACpD,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,kBAAkB,CAAC,CAuC7B"}
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { AdviceMap, FeltArray, Signature, TransactionSummary, Word, } from '@miden-sdk/miden-sdk';
|
|
2
|
-
import { buildConsumeNotesTransactionRequest, buildP2idTransactionRequest, buildUpdateGuardianTransactionRequest, buildUpdateProcedureThresholdTransactionRequest, buildUpdateSignersTransactionRequest, } from '../../transaction.js';
|
|
3
|
-
import { base64ToUint8Array, normalizeHexWord } from '../../utils/encoding.js';
|
|
4
|
-
import { buildSignatureAdviceEntry, signatureHexToBytes, tryComputeEcdsaCommitmentHex, } from '../../utils/signature.js';
|
|
5
|
-
import { computeCommitmentFromTxSummary } from '../helpers.js';
|
|
6
|
-
export async function executeProposalWorkflow(params) {
|
|
7
|
-
ensureProposalReady(params.proposal, params.threshold, params.getEffectiveThreshold);
|
|
8
|
-
const isSwitchGuardian = params.proposal.metadata.proposalType === 'switch_guardian';
|
|
9
|
-
const executionSource = await resolveExecutionSource(params.guardian, params.accountId, params.proposal, isSwitchGuardian);
|
|
10
|
-
const executionData = prepareExecutionData(executionSource.txSummaryBase64);
|
|
11
|
-
const adviceMap = buildCosignerAdviceMap(params.proposal, params.signerCommitments, executionData.txCommitmentHex);
|
|
12
|
-
if (!isSwitchGuardian && executionSource.delta) {
|
|
13
|
-
await appendGuardianAckAdvice(params.guardian, executionSource.delta, params.guardianCommitment, params.guardianPublicKey, params.signatureScheme, executionData.txCommitmentHex, adviceMap);
|
|
14
|
-
}
|
|
15
|
-
const finalRequest = await buildFinalRequest(params, executionData.saltHex, adviceMap);
|
|
16
|
-
await submitTransaction(params.midenClient, params.accountId, finalRequest);
|
|
17
|
-
}
|
|
18
|
-
export async function createTransactionProposalRequest(params) {
|
|
19
|
-
ensureProposalReady(params.proposal, params.threshold, params.getEffectiveThreshold);
|
|
20
|
-
const isSwitchGuardian = params.proposal.metadata.proposalType === 'switch_guardian';
|
|
21
|
-
const executionSource = await resolveExecutionSource(params.guardian, params.accountId, params.proposal, isSwitchGuardian);
|
|
22
|
-
const executionData = prepareExecutionData(executionSource.txSummaryBase64);
|
|
23
|
-
const adviceMap = buildCosignerAdviceMap(params.proposal, params.signerCommitments, executionData.txCommitmentHex);
|
|
24
|
-
if (!isSwitchGuardian && executionSource.delta) {
|
|
25
|
-
await appendGuardianAckAdvice(params.guardian, executionSource.delta, params.guardianCommitment, params.guardianPublicKey, params.signatureScheme, executionData.txCommitmentHex, adviceMap);
|
|
26
|
-
}
|
|
27
|
-
return await buildFinalRequest(params, executionData.saltHex, adviceMap);
|
|
28
|
-
}
|
|
29
|
-
function ensureProposalReady(proposal, defaultThreshold, getEffectiveThreshold) {
|
|
30
|
-
const proposalType = proposal.metadata?.proposalType;
|
|
31
|
-
const effectiveThreshold = proposalType
|
|
32
|
-
? getEffectiveThreshold(proposalType)
|
|
33
|
-
: defaultThreshold;
|
|
34
|
-
if (proposal.signatures.length < effectiveThreshold) {
|
|
35
|
-
throw new Error('Proposal is not ready for execution. Still pending signatures.');
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
async function resolveExecutionSource(guardian, accountId, proposal, isSwitchGuardian) {
|
|
39
|
-
if (isSwitchGuardian) {
|
|
40
|
-
return { txSummaryBase64: proposal.txSummary };
|
|
41
|
-
}
|
|
42
|
-
const deltas = await guardian.getDeltaProposals(accountId);
|
|
43
|
-
const delta = deltas.find((d) => computeCommitmentFromTxSummary(d.deltaPayload.txSummary.data) === proposal.commitment);
|
|
44
|
-
if (!delta) {
|
|
45
|
-
throw new Error(`Proposal not found on server: ${proposal.commitment}`);
|
|
46
|
-
}
|
|
47
|
-
return {
|
|
48
|
-
delta,
|
|
49
|
-
txSummaryBase64: delta.deltaPayload.txSummary.data,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
function prepareExecutionData(txSummaryBase64) {
|
|
53
|
-
const txSummaryBytes = base64ToUint8Array(txSummaryBase64);
|
|
54
|
-
const txSummary = TransactionSummary.deserialize(txSummaryBytes);
|
|
55
|
-
const saltHex = txSummary.salt().toHex();
|
|
56
|
-
const txCommitmentHex = txSummary.toCommitment().toHex();
|
|
57
|
-
return { txSummary, saltHex, txCommitmentHex };
|
|
58
|
-
}
|
|
59
|
-
function buildCosignerAdviceMap(proposal, signerCommitments, txCommitmentHex) {
|
|
60
|
-
const adviceMap = new AdviceMap();
|
|
61
|
-
const normalizedSignerCommitments = new Set(signerCommitments.map((c) => normalizeHexWord(c)));
|
|
62
|
-
for (const cosignerSig of proposal.signatures) {
|
|
63
|
-
let signerCommitmentHex = normalizeHexWord(cosignerSig.signerId);
|
|
64
|
-
if (cosignerSig.signature.scheme === 'ecdsa' && cosignerSig.signature.publicKey) {
|
|
65
|
-
const derived = tryComputeEcdsaCommitmentHex(cosignerSig.signature.publicKey);
|
|
66
|
-
if (derived && derived !== signerCommitmentHex) {
|
|
67
|
-
if (!normalizedSignerCommitments.has(derived)) {
|
|
68
|
-
throw new Error(`ECDSA public key commitment mismatch: derived commitment ${derived} is not in signerCommitments.`);
|
|
69
|
-
}
|
|
70
|
-
signerCommitmentHex = derived;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
const signerCommitment = Word.fromHex(signerCommitmentHex);
|
|
74
|
-
const sigBytes = signatureHexToBytes(cosignerSig.signature.signature, cosignerSig.signature.scheme);
|
|
75
|
-
const signature = Signature.deserialize(sigBytes);
|
|
76
|
-
const txCommitment = Word.fromHex(normalizeHexWord(txCommitmentHex));
|
|
77
|
-
const ecdsaPublicKey = cosignerSig.signature.scheme === 'ecdsa'
|
|
78
|
-
? cosignerSig.signature.publicKey
|
|
79
|
-
: undefined;
|
|
80
|
-
const isEcdsa = cosignerSig.signature.scheme === 'ecdsa' && Boolean(ecdsaPublicKey);
|
|
81
|
-
const { key, values } = buildSignatureAdviceEntry(signerCommitment, txCommitment, signature, ecdsaPublicKey, isEcdsa ? cosignerSig.signature.signature : undefined);
|
|
82
|
-
adviceMap.insert(key, new FeltArray(values));
|
|
83
|
-
}
|
|
84
|
-
return adviceMap;
|
|
85
|
-
}
|
|
86
|
-
async function appendGuardianAckAdvice(guardian, delta, guardianCommitmentHex, guardianPublicKey, defaultAckScheme, txCommitmentHex, adviceMap) {
|
|
87
|
-
const executionDelta = {
|
|
88
|
-
...delta,
|
|
89
|
-
deltaPayload: delta.deltaPayload.txSummary,
|
|
90
|
-
};
|
|
91
|
-
const pushResult = await guardian.pushDelta(executionDelta);
|
|
92
|
-
const ackSigHex = pushResult.ackSig;
|
|
93
|
-
if (!ackSigHex) {
|
|
94
|
-
throw new Error('GUARDIAN did not return acknowledgment signature');
|
|
95
|
-
}
|
|
96
|
-
const guardianAckScheme = pushResult.ackScheme || defaultAckScheme;
|
|
97
|
-
const ackPubkey = pushResult.ackPubkey || guardianPublicKey;
|
|
98
|
-
const normalizedGuardianCommitment = normalizeHexWord(guardianCommitmentHex);
|
|
99
|
-
if (guardianAckScheme === 'ecdsa' && ackPubkey) {
|
|
100
|
-
const derived = tryComputeEcdsaCommitmentHex(ackPubkey);
|
|
101
|
-
if (derived && derived !== normalizedGuardianCommitment) {
|
|
102
|
-
throw new Error('GUARDIAN public key commitment mismatch');
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
const guardianCommitment = Word.fromHex(normalizedGuardianCommitment);
|
|
106
|
-
const ackSigBytes = signatureHexToBytes(ackSigHex, guardianAckScheme);
|
|
107
|
-
const ackSignature = Signature.deserialize(ackSigBytes);
|
|
108
|
-
const txCommitment = Word.fromHex(normalizeHexWord(txCommitmentHex));
|
|
109
|
-
const isAckEcdsa = guardianAckScheme === 'ecdsa' && ackPubkey;
|
|
110
|
-
const { key, values } = buildSignatureAdviceEntry(guardianCommitment, txCommitment, ackSignature, isAckEcdsa ? ackPubkey : undefined, isAckEcdsa ? ackSigHex : undefined);
|
|
111
|
-
adviceMap.insert(key, new FeltArray(values));
|
|
112
|
-
}
|
|
113
|
-
async function buildFinalRequest(params, saltHex, adviceMap) {
|
|
114
|
-
const metadata = params.proposal.metadata;
|
|
115
|
-
const normalizedSalt = Word.fromHex(normalizeHexWord(saltHex));
|
|
116
|
-
switch (metadata.proposalType) {
|
|
117
|
-
case 'consume_notes': {
|
|
118
|
-
if (!metadata.noteIds || metadata.noteIds.length === 0) {
|
|
119
|
-
throw new Error('Proposal missing noteIds. Was it created with createConsumeNotesProposal?');
|
|
120
|
-
}
|
|
121
|
-
const { request } = await buildConsumeNotesTransactionRequest(params.midenClient, metadata.noteIds, { salt: normalizedSalt, signatureAdviceMap: adviceMap });
|
|
122
|
-
return request;
|
|
123
|
-
}
|
|
124
|
-
case 'switch_guardian': {
|
|
125
|
-
if (!metadata.newGuardianPubkey) {
|
|
126
|
-
throw new Error('Proposal missing newGuardianPubkey. Was it created with createSwitchGuardianProposal?');
|
|
127
|
-
}
|
|
128
|
-
const { request } = await buildUpdateGuardianTransactionRequest(params.midenClient, metadata.newGuardianPubkey, {
|
|
129
|
-
salt: normalizedSalt,
|
|
130
|
-
signatureAdviceMap: adviceMap,
|
|
131
|
-
signatureScheme: params.signatureScheme,
|
|
132
|
-
});
|
|
133
|
-
return request;
|
|
134
|
-
}
|
|
135
|
-
case 'update_procedure_threshold': {
|
|
136
|
-
const { request } = await buildUpdateProcedureThresholdTransactionRequest(params.midenClient, metadata.targetProcedure, metadata.targetThreshold, {
|
|
137
|
-
salt: normalizedSalt,
|
|
138
|
-
signatureAdviceMap: adviceMap,
|
|
139
|
-
signatureScheme: params.signatureScheme,
|
|
140
|
-
});
|
|
141
|
-
return request;
|
|
142
|
-
}
|
|
143
|
-
case 'p2id': {
|
|
144
|
-
if (!metadata.recipientId || !metadata.faucetId || !metadata.amount) {
|
|
145
|
-
throw new Error('Proposal missing P2ID metadata (recipientId, faucetId, amount). Was it created with createP2idProposal?');
|
|
146
|
-
}
|
|
147
|
-
const { request } = buildP2idTransactionRequest(params.accountId, metadata.recipientId, metadata.faucetId, BigInt(metadata.amount), { salt: normalizedSalt, signatureAdviceMap: adviceMap });
|
|
148
|
-
return request;
|
|
149
|
-
}
|
|
150
|
-
case 'custom':
|
|
151
|
-
throw new Error(`Cannot execute a custom proposal type (${metadata.rawProposalType ?? 'custom'}) via the generic SDK; ` +
|
|
152
|
-
'use prepareCustomExecution to get the cosigner + GUARDIAN advice, then submitTransaction with your rebuilt request (issue #266).');
|
|
153
|
-
default: {
|
|
154
|
-
const { request } = await buildUpdateSignersTransactionRequest(params.midenClient, metadata.targetThreshold, metadata.targetSignerCommitments, {
|
|
155
|
-
salt: normalizedSalt,
|
|
156
|
-
signatureAdviceMap: adviceMap,
|
|
157
|
-
signatureScheme: params.signatureScheme,
|
|
158
|
-
});
|
|
159
|
-
return request;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
async function submitTransaction(midenClient, accountIdHex, request) {
|
|
164
|
-
await midenClient.transactions.submit(accountIdHex, request);
|
|
165
|
-
}
|
|
166
|
-
//# sourceMappingURL=execution.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../../src/multisig/proposal/execution.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { DeltaObject, DeltaStatus, ProposalMetadata as GuardianProposalMetadata } from '@openzeppelin/guardian-client';
|
|
2
|
-
import type { ProposalMetadata, ProposalType, TransactionProposal, TransactionProposalSignature, TransactionProposalStatus } from '../../types.js';
|
|
3
|
-
export declare function buildGuardianMetadata(metadata: ProposalMetadata): GuardianProposalMetadata;
|
|
4
|
-
export declare function fromGuardianMetadata(guardian: GuardianProposalMetadata): ProposalMetadata | undefined;
|
|
5
|
-
export declare function deltaStatusToProposalStatus(status: DeltaStatus, signaturesRequired: number): TransactionProposalStatus;
|
|
6
|
-
interface DeltaToProposalParams {
|
|
7
|
-
delta: DeltaObject;
|
|
8
|
-
proposalId: string;
|
|
9
|
-
metadata: ProposalMetadata;
|
|
10
|
-
signaturesRequired: number;
|
|
11
|
-
existingSignatures?: TransactionProposalSignature[];
|
|
12
|
-
}
|
|
13
|
-
export declare function deltaToProposal({ delta, proposalId, metadata, signaturesRequired, existingSignatures, }: DeltaToProposalParams): TransactionProposal;
|
|
14
|
-
export declare function resolveMetadata(delta: DeltaObject, existingMetadata?: ProposalMetadata): ProposalMetadata | undefined;
|
|
15
|
-
export declare function signatureRequirementForProposal(metadata: ProposalMetadata, defaultThreshold: number, getEffectiveThreshold: (proposalType: ProposalType) => number): number;
|
|
16
|
-
export {};
|
|
17
|
-
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/multisig/proposal/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,gBAAgB,IAAI,wBAAwB,EAC7C,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,4BAA4B,EAC5B,yBAAyB,EAC1B,MAAM,gBAAgB,CAAC;AAExB,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,wBAAwB,CAyC1F;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,gBAAgB,GAAG,SAAS,CA4CrG;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,WAAW,EACnB,kBAAkB,EAAE,MAAM,GACzB,yBAAyB,CAoB3B;AAED,UAAU,qBAAqB;IAC7B,KAAK,EAAE,WAAW,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,4BAA4B,EAAE,CAAC;CACrD;AAED,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,UAAU,EACV,QAAQ,EACR,kBAAkB,EAClB,kBAAkB,GACnB,EAAE,qBAAqB,GAAG,mBAAmB,CA+B7C;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,WAAW,EAClB,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,gBAAgB,GAAG,SAAS,CAI9B;AAED,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,gBAAgB,EAC1B,gBAAgB,EAAE,MAAM,EACxB,qBAAqB,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,MAAM,GAC5D,MAAM,CAGR"}
|