@openzeppelin/miden-multisig-client 0.15.2 → 0.16.1
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 +37 -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 +17 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +14 -7
- 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 +14 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -3
- package/dist/index.js.map +1 -1
- package/dist/multisig.d.ts +130 -8
- package/dist/multisig.d.ts.map +1 -1
- package/dist/multisig.js +220 -24
- package/dist/multisig.js.map +1 -1
- package/dist/multisig.test.js +427 -89
- package/dist/multisig.test.js.map +1 -1
- package/dist/proposal/factory.d.ts.map +1 -1
- package/dist/proposal/factory.js +10 -0
- package/dist/proposal/factory.js.map +1 -1
- package/dist/proposal/factory.test.d.ts +2 -0
- package/dist/proposal/factory.test.d.ts.map +1 -0
- package/dist/proposal/factory.test.js +32 -0
- package/dist/proposal/factory.test.js.map +1 -0
- 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/prover/config.d.ts +16 -0
- package/dist/prover/config.d.ts.map +1 -0
- package/dist/prover/config.js +54 -0
- package/dist/prover/config.js.map +1 -0
- package/dist/prover/config.test.d.ts +2 -0
- package/dist/prover/config.test.d.ts.map +1 -0
- package/dist/prover/config.test.js +54 -0
- package/dist/prover/config.test.js.map +1 -0
- package/dist/prover/errors.d.ts +2 -0
- package/dist/prover/errors.d.ts.map +1 -0
- package/dist/prover/errors.js +158 -0
- package/dist/prover/errors.js.map +1 -0
- package/dist/prover/errors.test.d.ts +2 -0
- package/dist/prover/errors.test.d.ts.map +1 -0
- package/dist/prover/errors.test.js +24 -0
- package/dist/prover/errors.test.js.map +1 -0
- package/dist/prover/retry.d.ts +10 -0
- package/dist/prover/retry.d.ts.map +1 -0
- package/dist/prover/retry.js +32 -0
- package/dist/prover/retry.js.map +1 -0
- package/dist/prover/retry.test.d.ts +2 -0
- package/dist/prover/retry.test.d.ts.map +1 -0
- package/dist/prover/retry.test.js +20 -0
- package/dist/prover/retry.test.js.map +1 -0
- package/dist/prover/workflow.d.ts +11 -0
- package/dist/prover/workflow.d.ts.map +1 -0
- package/dist/prover/workflow.js +18 -0
- package/dist/prover/workflow.js.map +1 -0
- package/dist/prover/workflow.test.d.ts +2 -0
- package/dist/prover/workflow.test.d.ts.map +1 -0
- package/dist/prover/workflow.test.js +80 -0
- package/dist/prover/workflow.test.js.map +1 -0
- 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/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 +27 -2
- package/dist/transaction/p2id.d.ts.map +1 -1
- package/dist/transaction/p2id.js +56 -4
- 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/package.json +3 -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 +35 -12
- package/src/connectivity.test.ts +67 -0
- package/src/connectivity.ts +111 -0
- package/src/index.ts +25 -1
- package/src/multisig.test.ts +526 -94
- package/src/multisig.ts +270 -25
- package/src/proposal/factory.test.ts +40 -0
- package/src/proposal/factory.ts +11 -1
- package/src/proposal/metadata.test.ts +60 -0
- package/src/proposal/metadata.ts +14 -0
- package/src/prover/config.test.ts +90 -0
- package/src/prover/config.ts +78 -0
- package/src/prover/errors.test.ts +53 -0
- package/src/prover/errors.ts +178 -0
- package/src/prover/retry.test.ts +38 -0
- package/src/prover/retry.ts +46 -0
- package/src/prover/test-node.d.ts +6 -0
- package/src/prover/workflow.test.ts +109 -0
- package/src/prover/workflow.ts +19 -0
- package/src/raw-client.test.ts +41 -3
- package/src/raw-client.ts +15 -5
- 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 +91 -12
- 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 +4 -0
- package/src/types/proposal.ts +9 -0
package/src/raw-client.ts
CHANGED
|
@@ -5,8 +5,6 @@ import {
|
|
|
5
5
|
WasmWebClient,
|
|
6
6
|
} from '@miden-sdk/miden-sdk';
|
|
7
7
|
|
|
8
|
-
export const DEFAULT_MIDEN_RPC_URL = 'https://rpc.devnet.miden.io';
|
|
9
|
-
|
|
10
8
|
export type RawClientSource = MidenClient | WasmWebClient;
|
|
11
9
|
export interface ScriptLibrarySource {
|
|
12
10
|
namespace: string;
|
|
@@ -16,8 +14,19 @@ export interface ScriptLibrarySource {
|
|
|
16
14
|
|
|
17
15
|
const rawClientCache = new WeakMap<MidenClient, Promise<WasmWebClient>>();
|
|
18
16
|
|
|
19
|
-
export function
|
|
20
|
-
|
|
17
|
+
export function requireConfigValue(field: string, value?: unknown): string {
|
|
18
|
+
if (typeof value !== 'string') {
|
|
19
|
+
throw new Error(`missing required configuration: ${field}`);
|
|
20
|
+
}
|
|
21
|
+
const normalizedValue = value.trim();
|
|
22
|
+
if (normalizedValue === '') {
|
|
23
|
+
throw new Error(`missing required configuration: ${field}`);
|
|
24
|
+
}
|
|
25
|
+
return normalizedValue;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function requireMidenRpcEndpoint(endpoint?: string): string {
|
|
29
|
+
return requireConfigValue('midenRpcEndpoint', endpoint);
|
|
21
30
|
}
|
|
22
31
|
|
|
23
32
|
function isPublicMidenClient(client: RawClientSource): client is MidenClient {
|
|
@@ -37,8 +46,9 @@ export async function getRawMidenClient(
|
|
|
37
46
|
return cached;
|
|
38
47
|
}
|
|
39
48
|
|
|
49
|
+
const endpoint = requireMidenRpcEndpoint(rpcUrl);
|
|
40
50
|
const rawClient = WasmWebClient.createClient(
|
|
41
|
-
|
|
51
|
+
endpoint,
|
|
42
52
|
undefined,
|
|
43
53
|
undefined,
|
|
44
54
|
await client.storeIdentifier(),
|
|
@@ -15,7 +15,7 @@ import { LegacyConsumeNotesNoteMissingError } from '../multisig/consumeNotesErro
|
|
|
15
15
|
import { getRawMidenClient } from '../raw-client.js';
|
|
16
16
|
import { normalizeHexWord } from '../utils/encoding.js';
|
|
17
17
|
import { randomWord } from '../utils/random.js';
|
|
18
|
-
import type { SignatureOptions } from './options.js';
|
|
18
|
+
import type { MidenClientSignatureOptions, SignatureOptions } from './options.js';
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Build a consume-notes request from loaded `Note` objects (no local-store
|
|
@@ -57,6 +57,16 @@ export function buildConsumeNotesTransactionRequestFromNotes(
|
|
|
57
57
|
* Legacy/creation adapter: fetches notes from the local store and delegates
|
|
58
58
|
* to the from-notes variant. v2 verification MUST NOT call this.
|
|
59
59
|
*/
|
|
60
|
+
export function buildConsumeNotesTransactionRequest(
|
|
61
|
+
client: MidenClient,
|
|
62
|
+
noteIds: string[],
|
|
63
|
+
options: MidenClientSignatureOptions,
|
|
64
|
+
): Promise<{ request: TransactionRequest; salt: Word }>;
|
|
65
|
+
export function buildConsumeNotesTransactionRequest(
|
|
66
|
+
client: WasmWebClient,
|
|
67
|
+
noteIds: string[],
|
|
68
|
+
options?: SignatureOptions,
|
|
69
|
+
): Promise<{ request: TransactionRequest; salt: Word }>;
|
|
60
70
|
export async function buildConsumeNotesTransactionRequest(
|
|
61
71
|
client: MidenClient | WasmWebClient,
|
|
62
72
|
noteIds: string[],
|
|
@@ -2,10 +2,13 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
2
2
|
import type { Word } from '@miden-sdk/miden-sdk';
|
|
3
3
|
|
|
4
4
|
const {
|
|
5
|
+
mockFromVaultKey,
|
|
6
|
+
mockFungibleAssetConstructor,
|
|
5
7
|
mockHashElements,
|
|
6
8
|
mockNormalizeHexWord,
|
|
7
9
|
mockRandomWord,
|
|
8
10
|
mockWordFromHex,
|
|
11
|
+
noteMetadataCalls,
|
|
9
12
|
saltFelts,
|
|
10
13
|
} = vi.hoisted(() => {
|
|
11
14
|
const saltFelts = [
|
|
@@ -16,6 +19,13 @@ const {
|
|
|
16
19
|
];
|
|
17
20
|
|
|
18
21
|
return {
|
|
22
|
+
mockFromVaultKey: vi.fn((vaultKey: unknown, amount: bigint) => ({
|
|
23
|
+
kind: 'asset-from-vault-key',
|
|
24
|
+
vaultKey,
|
|
25
|
+
amount,
|
|
26
|
+
})),
|
|
27
|
+
mockFungibleAssetConstructor: vi.fn(),
|
|
28
|
+
noteMetadataCalls: [] as unknown[][],
|
|
19
29
|
mockHashElements: vi.fn().mockReturnValue({ toString: () => 'serial' }),
|
|
20
30
|
mockNormalizeHexWord: vi.fn((hex: string) => hex),
|
|
21
31
|
mockRandomWord: vi.fn().mockReturnValue({
|
|
@@ -66,10 +76,12 @@ vi.mock('@miden-sdk/miden-sdk', () => {
|
|
|
66
76
|
|
|
67
77
|
class NoteMetadata {
|
|
68
78
|
constructor(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
) {
|
|
79
|
+
sender: unknown,
|
|
80
|
+
noteType: unknown,
|
|
81
|
+
noteTag: unknown,
|
|
82
|
+
) {
|
|
83
|
+
noteMetadataCalls.push([sender, noteType, noteTag]);
|
|
84
|
+
}
|
|
73
85
|
}
|
|
74
86
|
|
|
75
87
|
class NoteRecipient {
|
|
@@ -89,7 +101,11 @@ vi.mock('@miden-sdk/miden-sdk', () => {
|
|
|
89
101
|
}
|
|
90
102
|
|
|
91
103
|
class FungibleAsset {
|
|
92
|
-
constructor(
|
|
104
|
+
constructor(faucet: unknown, amount: bigint) {
|
|
105
|
+
mockFungibleAssetConstructor(faucet, amount);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
static fromVaultKey = mockFromVaultKey;
|
|
93
109
|
}
|
|
94
110
|
|
|
95
111
|
class NoteArray {
|
|
@@ -120,6 +136,7 @@ vi.mock('@miden-sdk/miden-sdk', () => {
|
|
|
120
136
|
hex,
|
|
121
137
|
prefix: () => 1,
|
|
122
138
|
suffix: () => 2,
|
|
139
|
+
toString: () => hex,
|
|
123
140
|
})),
|
|
124
141
|
},
|
|
125
142
|
Felt,
|
|
@@ -140,7 +157,8 @@ vi.mock('@miden-sdk/miden-sdk', () => {
|
|
|
140
157
|
withAccountTarget: vi.fn(() => ({ kind: 'tag' })),
|
|
141
158
|
},
|
|
142
159
|
NoteType: {
|
|
143
|
-
|
|
160
|
+
Private: 0,
|
|
161
|
+
Public: 1,
|
|
144
162
|
},
|
|
145
163
|
OutputNote: {
|
|
146
164
|
full: vi.fn((note: unknown) => ({ note })),
|
|
@@ -163,14 +181,32 @@ vi.mock('../utils/random.js', () => ({
|
|
|
163
181
|
randomWord: mockRandomWord,
|
|
164
182
|
}));
|
|
165
183
|
|
|
166
|
-
import { buildP2idTransactionRequest } from './p2id.js';
|
|
184
|
+
import { buildP2idTransactionRequest, parseP2idNoteType, p2idNoteTypeToMetadata } from './p2id.js';
|
|
185
|
+
import type { Account } from '@miden-sdk/miden-sdk';
|
|
186
|
+
|
|
187
|
+
const FAUCET_ID = '0x7bfb0f38b0fafa103f86a805594171';
|
|
188
|
+
|
|
189
|
+
const mockAccount = {
|
|
190
|
+
vault: () => ({
|
|
191
|
+
fungibleAssets: () => [
|
|
192
|
+
{
|
|
193
|
+
faucetId: () => ({ toString: () => FAUCET_ID }),
|
|
194
|
+
vaultKey: () => ({ kind: 'vault-key' }),
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
}),
|
|
198
|
+
} as unknown as Account;
|
|
199
|
+
import { NoteType } from '@miden-sdk/miden-sdk';
|
|
167
200
|
|
|
168
201
|
describe('buildP2idTransactionRequest', () => {
|
|
169
202
|
beforeEach(() => {
|
|
203
|
+
mockFromVaultKey.mockClear();
|
|
204
|
+
mockFungibleAssetConstructor.mockClear();
|
|
170
205
|
mockHashElements.mockClear();
|
|
171
206
|
mockNormalizeHexWord.mockClear();
|
|
172
207
|
mockRandomWord.mockClear();
|
|
173
208
|
mockWordFromHex.mockClear();
|
|
209
|
+
noteMetadataCalls.length = 0;
|
|
174
210
|
});
|
|
175
211
|
|
|
176
212
|
it('derives serial number from salt felts plus four zero felts', () => {
|
|
@@ -179,8 +215,9 @@ describe('buildP2idTransactionRequest', () => {
|
|
|
179
215
|
buildP2idTransactionRequest(
|
|
180
216
|
'0x7bfb0f38b0fafa103f86a805594170',
|
|
181
217
|
'0x8a65fc5a39e4cd106d648e3eb4ab5f',
|
|
182
|
-
|
|
218
|
+
FAUCET_ID,
|
|
183
219
|
10n,
|
|
220
|
+
mockAccount,
|
|
184
221
|
{ salt },
|
|
185
222
|
);
|
|
186
223
|
|
|
@@ -197,4 +234,57 @@ describe('buildP2idTransactionRequest', () => {
|
|
|
197
234
|
expect((felt as { value: bigint }).value).toBe(0n);
|
|
198
235
|
}
|
|
199
236
|
});
|
|
237
|
+
|
|
238
|
+
it('creates a public note by default (issue #322)', () => {
|
|
239
|
+
buildP2idTransactionRequest(
|
|
240
|
+
'0x7bfb0f38b0fafa103f86a805594170',
|
|
241
|
+
'0x8a65fc5a39e4cd106d648e3eb4ab5f',
|
|
242
|
+
'0x7bfb0f38b0fafa103f86a805594171',
|
|
243
|
+
10n,
|
|
244
|
+
mockAccount,
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
expect(noteMetadataCalls).toHaveLength(1);
|
|
248
|
+
expect(noteMetadataCalls[0][1]).toBe(NoteType.Public);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it('threads the requested noteType into the note metadata (issue #322)', () => {
|
|
252
|
+
buildP2idTransactionRequest(
|
|
253
|
+
'0x7bfb0f38b0fafa103f86a805594170',
|
|
254
|
+
'0x8a65fc5a39e4cd106d648e3eb4ab5f',
|
|
255
|
+
'0x7bfb0f38b0fafa103f86a805594171',
|
|
256
|
+
10n,
|
|
257
|
+
mockAccount,
|
|
258
|
+
{ noteType: NoteType.Private },
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
expect(noteMetadataCalls).toHaveLength(1);
|
|
262
|
+
expect(noteMetadataCalls[0][1]).toBe(NoteType.Private);
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
describe('parseP2idNoteType', () => {
|
|
267
|
+
it('maps absent to Public (pre-#322 proposals)', () => {
|
|
268
|
+
expect(parseP2idNoteType(undefined)).toBe(NoteType.Public);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('maps wire values to note types', () => {
|
|
272
|
+
expect(parseP2idNoteType('public')).toBe(NoteType.Public);
|
|
273
|
+
expect(parseP2idNoteType('private')).toBe(NoteType.Private);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('rejects unknown values instead of silently rebuilding a public note', () => {
|
|
277
|
+
expect(() => parseP2idNoteType('encrypted')).toThrow(/unsupported metadata.noteType/);
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
describe('p2idNoteTypeToMetadata', () => {
|
|
282
|
+
it('omits the default so public payloads keep the legacy wire shape', () => {
|
|
283
|
+
expect(p2idNoteTypeToMetadata(undefined)).toBeUndefined();
|
|
284
|
+
expect(p2idNoteTypeToMetadata(NoteType.Public)).toBeUndefined();
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
it('serializes private', () => {
|
|
288
|
+
expect(p2idNoteTypeToMetadata(NoteType.Private)).toBe('private');
|
|
289
|
+
});
|
|
200
290
|
});
|
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,
|
|
@@ -56,27 +114,48 @@ function buildP2idNote(
|
|
|
56
114
|
return new Note(noteAssets, noteMetadata, noteRecipient);
|
|
57
115
|
}
|
|
58
116
|
|
|
59
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Rebuilds the P2ID note a proposal creates, from its metadata fields. The
|
|
119
|
+
* note is deterministic in the salt, so the resulting ID matches the note the
|
|
120
|
+
* proposal produces on execution (issue #356). The asset is derived from the
|
|
121
|
+
* account's current vault state, so call this before the transfer executes.
|
|
122
|
+
*/
|
|
123
|
+
export function buildP2idNoteFromMetadata(
|
|
60
124
|
senderId: string,
|
|
61
125
|
recipientId: string,
|
|
62
126
|
faucetId: string,
|
|
63
127
|
amount: bigint,
|
|
64
|
-
|
|
65
|
-
|
|
128
|
+
account: Account,
|
|
129
|
+
noteType: NoteType,
|
|
130
|
+
saltHex: string,
|
|
131
|
+
): Note {
|
|
66
132
|
const sender = AccountId.fromHex(senderId);
|
|
67
133
|
const recipient = AccountId.fromHex(recipientId);
|
|
68
134
|
const faucet = AccountId.fromHex(faucetId);
|
|
69
135
|
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
const asset = new FungibleAsset(faucet, amount);
|
|
136
|
+
const asset = resolveFungibleAssetFromVault(account, faucet, amount);
|
|
73
137
|
const noteAssets = new NoteAssets([asset]);
|
|
74
138
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
139
|
+
return buildP2idNote(sender, recipient, noteAssets, noteType, saltHex);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function buildP2idTransactionRequest(
|
|
143
|
+
senderId: string,
|
|
144
|
+
recipientId: string,
|
|
145
|
+
faucetId: string,
|
|
146
|
+
amount: bigint,
|
|
147
|
+
account: Account,
|
|
148
|
+
options: P2idTransactionOptions = {},
|
|
149
|
+
): { request: TransactionRequest; salt: Word } {
|
|
150
|
+
const authSaltHex = options.salt ? options.salt.toHex() : randomWord().toHex();
|
|
151
|
+
|
|
152
|
+
const note = buildP2idNoteFromMetadata(
|
|
153
|
+
senderId,
|
|
154
|
+
recipientId,
|
|
155
|
+
faucetId,
|
|
156
|
+
amount,
|
|
157
|
+
account,
|
|
158
|
+
options.noteType ?? NoteType.Public,
|
|
80
159
|
authSaltHex,
|
|
81
160
|
);
|
|
82
161
|
|
|
@@ -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
|
@@ -3,7 +3,11 @@ export {
|
|
|
3
3
|
} from './transaction/consumeNotes.js';
|
|
4
4
|
export { executeForSummary } from './transaction/summary.js';
|
|
5
5
|
export {
|
|
6
|
+
buildP2idNoteFromMetadata,
|
|
6
7
|
buildP2idTransactionRequest,
|
|
8
|
+
parseP2idNoteType,
|
|
9
|
+
p2idNoteTypeToMetadata,
|
|
10
|
+
type P2idTransactionOptions,
|
|
7
11
|
} from './transaction/p2id.js';
|
|
8
12
|
export {
|
|
9
13
|
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 {
|