11/**
22 * @prettier
3+ *
4+ * @experimental The vault client surface is experimental and may change (including breaking
5+ * changes) before the public release.
36 */
7+ import * as t from 'io-ts' ;
48import type { FreezeOptions , Wallet , WalletShare } from '../wallet' ;
9+ import * as VaultCodecs from './codecs' ;
510
6- /**
7- * The four static root-key slots of a vault, keyed by (curve, scheme):
8- * - secp256k1Multisig ① — UTXO/XRP/XTZ/TRX/EOS
9- * - ecdsaMpc ② — EVM/Cosmos (DKLS)
10- * - eddsaMpc ③ — SOL/SUI/NEAR/TON/APT/DOT
11- * - ed25519Multisig ④ — ALGO/XLM/HBAR
12- */
13- export type RootKeyType = 'secp256k1Multisig' | 'ecdsaMpc' | 'eddsaMpc' | 'ed25519Multisig' ;
14-
15- export type VaultPermission = 'view' | 'spend' | 'admin' | 'dapp' ;
11+ // ---- data shapes (derived from the io-ts codecs in ./codecs — single source of truth) ----
1612
17- /**
18- * The 12 static root key ids, by (curve, scheme). Each entry is an ordered
19- * [userKeyId, backupKeyId, bitgoKeyId] triplet — same shape and order as wallet.keys[].
20- */
21- export type VaultRootKeys = Record < RootKeyType , [ userKeyId : string , backupKeyId : string , bitgoKeyId : string ] > ;
22-
23- export interface VaultMembershipData {
24- userId : string ; // new-model naming convention
25- permissions : VaultPermission [ ] ;
26- needsRecovery ?: boolean ;
27- }
28-
29- /**
30- * A pending UMS spend grant awaiting a key share — mirror of the wallet's walletShareRequests[].
31- * Returned to spenders/admins and serviced via addMember.
32- */
33- export interface VaultShareRequest {
34- userId : string ;
35- permissions : VaultPermission [ ] ;
36- createdAt : string ;
37- }
38-
39- export interface VaultData {
40- id : string ;
41- enterpriseId : string ;
42- label : string ;
43- // freeze is NOT a status — a frozen vault stays 'active' with the freeze field set (wallet precedent)
44- status : 'initializing' | 'active' | 'archived' ;
45- creator : string ;
46- users : VaultMembershipData [ ] ;
47- vaultShareRequests ?: VaultShareRequest [ ] ;
48- freeze ?: { time ?: string ; expires ?: string ; reason ?: string } ;
49- rootKeys ?: VaultRootKeys ; // ordered, like wallet.keys
50- archivedAt ?: string ;
51- createdAt : string ;
52- }
13+ export type RootKeyType = t . TypeOf < typeof VaultCodecs . RootKeyType > ;
14+ export type VaultPermission = t . TypeOf < typeof VaultCodecs . VaultPermission > ;
15+ export type VaultRootKeys = t . TypeOf < typeof VaultCodecs . VaultRootKeys > ;
16+ export type VaultMembershipData = t . TypeOf < typeof VaultCodecs . VaultMembershipData > ;
17+ export type VaultShareRequest = t . TypeOf < typeof VaultCodecs . VaultShareRequest > ;
18+ export type VaultData = t . TypeOf < typeof VaultCodecs . VaultData > ;
19+ export type VaultShareState = t . TypeOf < typeof VaultCodecs . VaultShareState > ;
20+ export type VaultShareKeychain = t . TypeOf < typeof VaultCodecs . VaultShareKeychain > ;
21+ export type VaultShareData = t . TypeOf < typeof VaultCodecs . VaultShareData > ;
5322
5423export interface InitializeVaultOptions {
55- label : string ; // Phase 1 carries no key material — key generation happens in Phase 2 via the existing keychain APIs
24+ label : string ;
5625}
5726
5827// Phase 3 — the client hands back the 12 key ids it created in Phase 2:
5928export interface FinalizeVaultOptions {
6029 rootKeys : VaultRootKeys ;
6130}
6231
63- /** Vault key-share states — identical to WalletShare states, no new states. */
64- export type VaultShareState = 'pendingapproval' | 'active' | 'accepted' | 'canceled' | 'rejected' ;
65-
66- /**
67- * One of the 4 root USER keyshares carried on a VaultShare, ECDH-re-encrypted to the recipient.
68- * Body semantics land in the Part VI SDK ticket (WCN-1204).
69- */
70- export interface VaultShareKeychain {
71- rootKeyType : RootKeyType ;
72- rootKeyId : string ;
73- encryptedPrv : string ;
74- publicIdentifier : string ;
75- fromPubKey : string ;
76- toPubKey : string ;
77- path : string ;
78- }
79-
80- export interface VaultShareData {
81- id : string ;
82- enterpriseId : string ;
83- vaultId : string ;
84- vaultLabel ?: string ;
85- fromUser : string ;
86- toUser : string ;
87- permissions : VaultPermission [ ] ;
88- state : VaultShareState ;
89- message ?: string ;
90- pendingApprovalId ?: string ;
91- isUMSInitiated ?: boolean ;
92- keychains ?: VaultShareKeychain [ ] ;
93- createdAt : string ;
94- updatedAt ?: string ;
95- }
96-
9732/**
9833 * Sharing ONE vault wallet with a non-member rides the existing wallet-share handshake (FR-13),
9934 * so the result is the existing WalletShare shape.
@@ -106,34 +41,45 @@ export interface CreateVaultWalletOptions {
10641 coin : string ;
10742 label : string ;
10843 type ?: string ;
109- multisigType ?: string ;
11044 multisigTypeVersion ?: string ;
11145}
11246
113- export interface AddVaultMemberOptions {
114- userId ?: string ;
115- email ?: string ;
47+ interface AddVaultMemberBase {
11648 permissions : VaultPermission [ ] ;
117- // required when 'spend' is included — the 4 root user keys ECDH-re-encrypted to the invitee
49+ /** required when 'spend' is included — the 4 root user keys ECDH-re-encrypted to the invitee */
11850 keychains ?: VaultShareKeychain [ ] ;
11951 message ?: string ;
52+ /** when true, suppress the invitation email that would otherwise be sent to `email` */
12053 disableEmail ?: boolean ;
12154}
12255
56+ /** Add a member by either `userId` or `email` — exactly one is required. */
57+ export type AddVaultMemberOptions =
58+ | ( AddVaultMemberBase & { userId : string ; email ?: never } )
59+ | ( AddVaultMemberBase & { email : string ; userId ?: never } ) ;
60+
12361export interface AddVaultWalletMemberOptions {
12462 walletId : string ;
63+ /** required — sharing re-encrypts the user key, which needs hardened derivation from the passphrase */
64+ walletPassphrase : string ;
12565 email ?: string ;
12666 permissions ?: string [ ] ;
12767 message ?: string ;
12868}
12969
130- export interface AcceptVaultShareOptions {
70+ export type AcceptVaultShareAsSpenderOptions = {
13171 vaultShareId : string ;
132- userPassword ? : string ;
72+ userPassword : string ;
13373 newWalletPassphrase ?: string ;
134- overrideEncryptedPrv ?: string ;
135- }
74+ } ;
75+ export type AcceptVaultShareAsNonSpenderOptions = {
76+ vaultShareId : string ;
77+ } ;
78+ export type AcceptVaultShareOptions = AcceptVaultShareAsSpenderOptions | AcceptVaultShareAsNonSpenderOptions ;
13679
80+ /**
81+ * @experimental
82+ */
13783export interface IVault {
13884 id ( ) : string ;
13985 enterpriseId ( ) : string ;
@@ -144,7 +90,7 @@ export interface IVault {
14490 // whole-vault: view/admin/spend; spend opens a key share (also how a spender services a
14591 // vaultShareRequests entry in UMS orgs)
14692 addMember ( params : AddVaultMemberOptions ) : Promise < VaultData > ;
147- // share ONE vault wallet (FR-13) , not the whole vault
93+ // share ONE vault wallet, not the whole vault
14894 addMemberToWallet ( params : AddVaultWalletMemberOptions ) : Promise < WalletShareData > ;
14995 listShares ( params ?: { state ?: VaultShareState } ) : Promise < VaultShareData [ ] > ;
15096 acceptShare ( params : AcceptVaultShareOptions ) : Promise < VaultShareData > ;
0 commit comments