@@ -2,16 +2,24 @@ import {
22 AuditDecryptedKeyParams ,
33 BaseCoin ,
44 BitGoBase ,
5- KeyPair as KeyPairInterface ,
5+ KeyPair ,
66 ParseTransactionOptions ,
77 ParsedTransaction ,
88 SignTransactionOptions ,
99 SignedTransaction ,
10- VerifyAddressOptions ,
1110 VerifyTransactionOptions ,
11+ MultisigType ,
12+ multisigTypes ,
13+ MPCAlgorithm ,
14+ InvalidAddressError ,
15+ EDDSAMethods ,
16+ TssVerifyAddressOptions ,
17+ MPCType ,
1218} from '@bitgo/sdk-core' ;
1319import { BaseCoin as StaticsBaseCoin , CoinFamily } from '@bitgo/statics' ;
1420import utils from './lib/utils' ;
21+ import { KeyPair as IotaKeyPair } from './lib' ;
22+ import { auditEddsaPrivateKey } from '@bitgo/sdk-lib-mpc' ;
1523
1624export class Iota extends BaseCoin {
1725 protected readonly _staticsCoin : Readonly < StaticsBaseCoin > ;
@@ -46,6 +54,20 @@ export class Iota extends BaseCoin {
4654 return this . _staticsCoin . fullName ;
4755 }
4856
57+ /** @inheritDoc */
58+ supportsTss ( ) : boolean {
59+ return true ;
60+ }
61+
62+ /** inherited doc */
63+ getDefaultMultisigType ( ) : MultisigType {
64+ return multisigTypes . tss ;
65+ }
66+
67+ getMPCAlgorithm ( ) : MPCAlgorithm {
68+ return MPCType . EDDSA ;
69+ }
70+
4971 /**
5072 * Check if an address is valid
5173 * @param address the address to be validated
@@ -69,8 +91,30 @@ export class Iota extends BaseCoin {
6991 * Check if an address belongs to a wallet
7092 * @param params
7193 */
72- async isWalletAddress ( params : VerifyAddressOptions ) : Promise < boolean > {
73- return this . isValidAddress ( params . address ) ;
94+ async isWalletAddress ( params : TssVerifyAddressOptions ) : Promise < boolean > {
95+ const { keychains, address, index } = params ;
96+
97+ if ( ! this . isValidAddress ( address ) ) {
98+ throw new InvalidAddressError ( `invalid address: ${ address } ` ) ;
99+ }
100+
101+ if ( ! keychains ) {
102+ throw new Error ( 'missing required param keychains' ) ;
103+ }
104+
105+ for ( const keychain of keychains ) {
106+ const MPC = await EDDSAMethods . getInitializedMpcInstance ( ) ;
107+ const commonKeychain = keychain . commonKeychain as string ;
108+
109+ const derivationPath = 'm/' + index ;
110+ const derivedPublicKey = MPC . deriveUnhardened ( commonKeychain , derivationPath ) . slice ( 0 , 64 ) ;
111+ const expectedAddress = utils . getAddressFromPublicKey ( derivedPublicKey ) ;
112+
113+ if ( address !== expectedAddress ) {
114+ return false ;
115+ }
116+ }
117+ return true ;
74118 }
75119
76120 /**
@@ -86,12 +130,15 @@ export class Iota extends BaseCoin {
86130 * Generate a key pair
87131 * @param seed Optional seed to generate key pair from
88132 */
89- generateKeyPair ( seed ?: Uint8Array ) : KeyPairInterface {
90- // For now we're just returning an empty implementation as the KeyPair class needs to be implemented
91- // In a real implementation, we would use the KeyPair class properly
133+ generateKeyPair ( seed ?: Buffer ) : KeyPair {
134+ const keyPair = seed ? new IotaKeyPair ( { seed } ) : new IotaKeyPair ( ) ;
135+ const keys = keyPair . getKeys ( ) ;
136+ if ( ! keys . prv ) {
137+ throw new Error ( 'Missing prv in key generation.' ) ;
138+ }
92139 return {
93- pub : '' ,
94- prv : '' ,
140+ pub : keys . pub ,
141+ prv : keys . prv ,
95142 } ;
96143 }
97144
@@ -100,28 +147,25 @@ export class Iota extends BaseCoin {
100147 * @param pub Public key to check
101148 */
102149 isValidPub ( pub : string ) : boolean {
103- // TODO: Implement proper IOTA public key validation
104- return pub . length > 0 ;
150+ return utils . isValidPublicKey ( pub ) ;
105151 }
106152
107153 /**
108154 * Sign a transaction
109155 * @param params
110156 */
111157 async signTransaction ( params : SignTransactionOptions ) : Promise < SignedTransaction > {
112- // TODO: Add IOTA-specific transaction signing logic
113- return {
114- halfSigned : {
115- txHex : '' ,
116- } ,
117- } ;
158+ throw new Error ( 'Method not implemented.' ) ;
118159 }
119160
120161 /**
121162 * Audit a decrypted private key to ensure it's valid
122163 * @param params
123164 */
124- auditDecryptedKey ( params : AuditDecryptedKeyParams ) : void {
125- // TODO: Implement IOTA-specific key validation logic
165+ auditDecryptedKey ( { multiSigType, prv, publicKey } : AuditDecryptedKeyParams ) : void {
166+ if ( multiSigType !== multisigTypes . tss ) {
167+ throw new Error ( 'Unsupported multiSigType' ) ;
168+ }
169+ auditEddsaPrivateKey ( prv , publicKey ?? '' ) ;
126170 }
127171}
0 commit comments