Skip to content

Commit

Permalink
wip/frost-encryption, address book, stored identities (#4775)
Browse files Browse the repository at this point in the history
* adds walletdb multisigSecrets (#4735)

adds a datastore to the walletDb to store each 'ParticipantSecret' that a
multisig user generates

uses a string 'name' as the key and stores the secret as a buffer as the
datastore value

* adds wallet multisig rpc to create secret (#4737)

* adds wallet multisig rpc to create secret

provides an interface for generating a random ParticipantSecret and storing it
in the walletDb with a given name

updates wallet:multisig:identity:create to use the new RPC. perhaps we should
rename to 'wallet:multisig:secret:create'?

* changes createSecret to createIdentity

returns identity instead of exposing secret over rpc

* checks for duplicate names before creating identity

avoids overwriting secrets in the database!

reuses DUPLICATE_ACCOUNT_NAME error code, close enough

prompts for new name on collision

* addresses pr feedback

removes extra name prompt logic

removes unnecessary ParticipantIdentity construction

adds database transaction to rpc

* fixes typo

s/assoicate/associate/

* supports retrieving identities from walletdb (#4738)

adds getIdentity RPC to get an identity from the walletdb by name

adds wallet:multisig:identity command to get an identity and print it on the
command line

* adds participant 'address book' (#4569)

* adds participant 'address book'

adds a database store to the walletDb that stores identifiers for participants
in the signing group of a multisig account

'participantIdentifiers' uses a compound key consisting of the account prefix
and a participant identifier where each participant identifier is expected to be
a hex string

implements methods for adding, deleting, and iterating over identifiers

* uses 'pi' for participantIdentifiers datastore name

* renames to participantIdentities

we prefer to store Identities rather than Identifiers

* adds participant identity encoder

---------

Co-authored-by: Joe <[email protected]>

* fixes encoding of ParticipantIdentity on write (#4747)

the database implicitly uses the encoder to serialized values at the time of
writing to the database

serializing with the encoder before write results in a double-encoded value,
which produces a write error

adds unit test to walletdb test

* saves participant identities on account import (#4761)

* saves participant identities on account import

adds each participant identity from a PublicKeyPackage to the
participantIdentities store when importing a multisig account

adds napi bindings to deserialize a PublicKeyPackage and return the list of
identities as buffers

adds slow unit test to verify that identities are saved when importing multisig
accounts

* fixes test

removes fake public key package from import

* fixes tests

adds test utility to create trusted dealer key packages for random identities

replaces fake public key packages in import/export tests with generated public
key packages

removes bech32 test of multisig account import

replaces json test of multisig account import

* changes implementation of NativePublicKeyPackage.identities

no napi errors to handle, fewer allocations

* updates return type of identities

* supports listing identities for a multisig account (#4767)

* supports listing identities for a multisig account

adds wallet/multisig/getAccountIdentities RPC to return a list of all identities
for a given account. reads identities from the account's publicKeyPackage

adds wallet:multisig:account:identities CLI command that calls the above RPC and
logs each identity

* removes unnecessary 'required: false' for account flag

defaults to false

* verify that commitments all come from known identities (#4748)

* verify that commitments all come from known identities

adds account parameter to wallet/multisig/createSigningPackage

updates cli command with account flag

before creating signing package, verifies that the identity on each commitment
passed to createSigningPackage matches an identity in the set of all
identities for the group

uses getParticipantIdentities to build the set of identities

adds unit test

* updates cli flag description

* uses identities from publicKeyPackage to verify commitments

don't need to use address book just to list identities since they're all in the
publicKeyPackage

* regenerates outdated transaction fixture

---------

Co-authored-by: Joe <[email protected]>
  • Loading branch information
hughy and jowparks authored Feb 26, 2024
1 parent 8ee25c6 commit 2578019
Show file tree
Hide file tree
Showing 30 changed files with 795 additions and 34 deletions.
33 changes: 33 additions & 0 deletions ironfish-cli/src/commands/wallet/multisig/account/identities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import { Flags } from '@oclif/core'
import { IronfishCommand } from '../../../../command'
import { RemoteFlags } from '../../../../flags'

export class MultisigAccountIdentities extends IronfishCommand {
static description = `List the identities for a multisig account`
static hidden = true

static flags = {
...RemoteFlags,
account: Flags.string({
char: 'f',
description: 'The account to list identities for',
}),
}

async start(): Promise<void> {
const { flags } = await this.parse(MultisigAccountIdentities)

const client = await this.sdk.connectRpc()

const response = await client.wallet.multisig.getAccountIdentities({
account: flags.account,
})

for (const identity of response.content.identities) {
this.log(identity)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export class CreateSigningPackage extends IronfishCommand {

static flags = {
...RemoteFlags,
account: Flags.string({
char: 'f',
description: 'The account to use when creating the signing package',
required: false,
}),
unsignedTransaction: Flags.string({
char: 'u',
description: 'The unsigned transaction for which the signing share will be created',
Expand Down Expand Up @@ -48,6 +53,7 @@ export class CreateSigningPackage extends IronfishCommand {
const client = await this.sdk.connectRpc()

const signingPackageResponse = await client.wallet.multisig.createSigningPackage({
account: flags.account,
unsignedTransaction,
commitments,
})
Expand Down
41 changes: 35 additions & 6 deletions ironfish-cli/src/commands/wallet/multisig/identity/create.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,48 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import { ParticipantSecret } from '@ironfish/rust-nodejs'
import { RPC_ERROR_CODES, RpcRequestError } from '@ironfish/sdk'
import { CliUx, Flags } from '@oclif/core'
import { IronfishCommand } from '../../../../command'
import { RemoteFlags } from '../../../../flags'

export class MultisigIdentityCreate extends IronfishCommand {
static description = `Create a multisig identity`
static hidden = true

start(): void {
// TODO: generate secret over RPC, persist in walletDb
const secret = ParticipantSecret.random()
static flags = {
...RemoteFlags,
name: Flags.string({
char: 'n',
description: 'Name to associate with the identity',
required: true,
}),
}

async start(): Promise<void> {
const { flags } = await this.parse(MultisigIdentityCreate)

const client = await this.sdk.connectRpc()
let response
while (!response) {
try {
response = await client.wallet.multisig.createIdentity({ name: flags.name })
} catch (e) {
if (
e instanceof RpcRequestError &&
e.code === RPC_ERROR_CODES.DUPLICATE_ACCOUNT_NAME.toString()
) {
this.log()
this.log(e.codeMessage)
}

flags.name = await CliUx.ux.prompt('Enter a new name for the identity', {
required: true,
})
}
}

const identity = secret.toIdentity()
this.log('Identity:')
this.log(identity.serialize().toString('hex'))
this.log(response.content.identity)
}
}
31 changes: 31 additions & 0 deletions ironfish-cli/src/commands/wallet/multisig/identity/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import { Flags } from '@oclif/core'
import { IronfishCommand } from '../../../../command'
import { RemoteFlags } from '../../../../flags'

export class MultisigIdentity extends IronfishCommand {
static description = `Retrieve a multisig identity`
static hidden = true

static flags = {
...RemoteFlags,
name: Flags.string({
char: 'n',
description: 'Name of the identity',
required: true,
}),
}

async start(): Promise<void> {
const { flags } = await this.parse(MultisigIdentity)

const client = await this.sdk.connectRpc()

const response = await client.wallet.multisig.getIdentity({ name: flags.name })

this.log('Identity:')
this.log(response.content.identity)
}
}
6 changes: 6 additions & 0 deletions ironfish-rust-nodejs/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

/* auto-generated by NAPI-RS */

export const IDENTITY_LEN: number
export function createSigningCommitment(identity: string, keyPackage: string, transactionHash: Buffer, signers: Array<string>): string
export function createSignatureShare(identity: string, keyPackage: string, signingPackage: string): string
export function splitSecret(coordinatorSaplingKey: string, minSigners: number, identities: Array<string>): TrustedDealerKeyPackages
Expand Down Expand Up @@ -106,6 +107,11 @@ export class ParticipantIdentity {
constructor(jsBytes: Buffer)
serialize(): Buffer
}
export type NativePublicKeyPackage = PublicKeyPackage
export class PublicKeyPackage {
constructor(value: string)
identities(): Array<Buffer>
}
export class BoxKeyPair {
constructor()
static fromHex(secretHex: string): BoxKeyPair
Expand Down
4 changes: 3 additions & 1 deletion ironfish-rust-nodejs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,16 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}

const { FishHashContext, createSigningCommitment, createSignatureShare, ParticipantSecret, ParticipantIdentity, splitSecret, contribute, verifyTransform, KEY_LENGTH, NONCE_LENGTH, BoxKeyPair, randomBytes, boxMessage, unboxMessage, RollingFilter, initSignalHandler, triggerSegfault, ASSET_ID_LENGTH, ASSET_METADATA_LENGTH, ASSET_NAME_LENGTH, ASSET_LENGTH, Asset, NOTE_ENCRYPTION_KEY_LENGTH, MAC_LENGTH, ENCRYPTED_NOTE_PLAINTEXT_LENGTH, ENCRYPTED_NOTE_LENGTH, NoteEncrypted, PUBLIC_ADDRESS_LENGTH, RANDOMNESS_LENGTH, MEMO_LENGTH, AMOUNT_VALUE_LENGTH, DECRYPTED_NOTE_LENGTH, Note, PROOF_LENGTH, TRANSACTION_SIGNATURE_LENGTH, TRANSACTION_PUBLIC_KEY_RANDOMNESS_LENGTH, TRANSACTION_EXPIRATION_LENGTH, TRANSACTION_FEE_LENGTH, LATEST_TRANSACTION_VERSION, TransactionPosted, Transaction, verifyTransactions, UnsignedTransaction, aggregateSignatureShares, LanguageCode, generateKey, spendingKeyToWords, wordsToSpendingKey, generateKeyFromPrivateKey, initializeSapling, FoundBlockResult, ThreadPoolHandler, isValidPublicAddress } = nativeBinding
const { FishHashContext, IDENTITY_LEN, createSigningCommitment, createSignatureShare, ParticipantSecret, ParticipantIdentity, splitSecret, PublicKeyPackage, contribute, verifyTransform, KEY_LENGTH, NONCE_LENGTH, BoxKeyPair, randomBytes, boxMessage, unboxMessage, RollingFilter, initSignalHandler, triggerSegfault, ASSET_ID_LENGTH, ASSET_METADATA_LENGTH, ASSET_NAME_LENGTH, ASSET_LENGTH, Asset, NOTE_ENCRYPTION_KEY_LENGTH, MAC_LENGTH, ENCRYPTED_NOTE_PLAINTEXT_LENGTH, ENCRYPTED_NOTE_LENGTH, NoteEncrypted, PUBLIC_ADDRESS_LENGTH, RANDOMNESS_LENGTH, MEMO_LENGTH, AMOUNT_VALUE_LENGTH, DECRYPTED_NOTE_LENGTH, Note, PROOF_LENGTH, TRANSACTION_SIGNATURE_LENGTH, TRANSACTION_PUBLIC_KEY_RANDOMNESS_LENGTH, TRANSACTION_EXPIRATION_LENGTH, TRANSACTION_FEE_LENGTH, LATEST_TRANSACTION_VERSION, TransactionPosted, Transaction, verifyTransactions, UnsignedTransaction, aggregateSignatureShares, LanguageCode, generateKey, spendingKeyToWords, wordsToSpendingKey, generateKeyFromPrivateKey, initializeSapling, FoundBlockResult, ThreadPoolHandler, isValidPublicAddress } = nativeBinding

module.exports.FishHashContext = FishHashContext
module.exports.IDENTITY_LEN = IDENTITY_LEN
module.exports.createSigningCommitment = createSigningCommitment
module.exports.createSignatureShare = createSignatureShare
module.exports.ParticipantSecret = ParticipantSecret
module.exports.ParticipantIdentity = ParticipantIdentity
module.exports.splitSecret = splitSecret
module.exports.PublicKeyPackage = PublicKeyPackage
module.exports.contribute = contribute
module.exports.verifyTransform = verifyTransform
module.exports.KEY_LENGTH = KEY_LENGTH
Expand Down
34 changes: 33 additions & 1 deletion ironfish-rust-nodejs/src/frost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use ironfish::{
SaplingKey,
};
use ironfish_frost::{
nonces::deterministic_signing_nonces, signature_share::SignatureShare,
keys::PublicKeyPackage, nonces::deterministic_signing_nonces, signature_share::SignatureShare,
signing_commitment::SigningCommitment,
};
use napi::{bindgen_prelude::*, JsBuffer};
Expand All @@ -41,6 +41,11 @@ where
})
}

use ironfish::frost_utils::IDENTITY_LEN as ID_LEN;

#[napi]
pub const IDENTITY_LEN: u32 = ID_LEN as u32;

#[napi]
pub fn create_signing_commitment(
identity: String,
Expand Down Expand Up @@ -229,3 +234,30 @@ pub fn split_secret(
public_key_package: bytes_to_hex(&public_key_package_vec),
})
}

#[napi(js_name = "PublicKeyPackage")]
pub struct NativePublicKeyPackage {
public_key_package: PublicKeyPackage,
}

#[napi]
impl NativePublicKeyPackage {
#[napi(constructor)]
pub fn new(value: String) -> Result<NativePublicKeyPackage> {
let bytes = hex_to_vec_bytes(&value).map_err(to_napi_err)?;

let public_key_package =
PublicKeyPackage::deserialize_from(&bytes[..]).map_err(to_napi_err)?;

Ok(NativePublicKeyPackage { public_key_package })
}

#[napi]
pub fn identities(&self) -> Vec<Buffer> {
self.public_key_package
.identities()
.iter()
.map(|identity| Buffer::from(&identity.serialize()[..]))
.collect()
}
}
2 changes: 2 additions & 0 deletions ironfish-rust/src/frost_utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
pub mod signing_package;
pub mod split_secret;
pub mod split_spender_key;
pub use ironfish_frost::keys::PublicKeyPackage;
pub use ironfish_frost::participant::IDENTITY_LEN;
34 changes: 34 additions & 0 deletions ironfish/src/rpc/clients/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import type {
BurnAssetResponse,
CreateAccountRequest,
CreateAccountResponse,
CreateIdentityRequest,
CreateIdentityResponse,
CreateSignatureShareRequest,
CreateSignatureShareResponse,
CreateSigningCommitmentRequest,
Expand All @@ -41,6 +43,8 @@ import type {
ExportChainStreamResponse,
FollowChainStreamRequest,
FollowChainStreamResponse,
GetAccountIdentitiesRequest,
GetAccountIdentitiesResponse,
GetAccountNotesStreamRequest,
GetAccountNotesStreamResponse,
GetAccountsRequest,
Expand Down Expand Up @@ -77,6 +81,8 @@ import type {
GetDifficultyResponse,
GetFundsRequest,
GetFundsResponse,
GetIdentityRequest,
GetIdentityResponse,
GetLogStreamResponse,
GetMempoolStatusResponse,
GetMempoolTransactionResponse,
Expand Down Expand Up @@ -227,7 +233,35 @@ export abstract class RpcClient {
params,
).waitForEnd()
},

createIdentity: (
params: CreateIdentityRequest,
): Promise<RpcResponseEnded<CreateIdentityResponse>> => {
return this.request<CreateIdentityResponse>(
`${ApiNamespace.wallet}/multisig/createIdentity`,
params,
).waitForEnd()
},

getIdentity: (
params: GetIdentityRequest,
): Promise<RpcResponseEnded<GetIdentityResponse>> => {
return this.request<GetIdentityResponse>(
`${ApiNamespace.wallet}/multisig/getIdentity`,
params,
).waitForEnd()
},

getAccountIdentities: (
params: GetAccountIdentitiesRequest,
): Promise<RpcResponseEnded<GetAccountIdentitiesResponse>> => {
return this.request<GetAccountIdentitiesResponse>(
`${ApiNamespace.wallet}/multisig/getAccountIdentities`,
params,
).waitForEnd()
},
},

getAccounts: (
params: GetAccountsRequest = undefined,
): Promise<RpcResponseEnded<GetAccountsResponse>> => {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":4,"id":"6edfda50-ec03-4236-b6d2-a47ffaf06e9a","name":"f461cbaacc835efd1d1330140b1cfeffc60c0a6c007b82b255d9f8b3f5cdf20d","spendingKey":null,"viewKey":"37643a564836f46215930fed8493cf3ea11ed1efb13a498e5eaf51f332459d0cb482f9f224c550557164a1dffa1567b01c22c5c91e4867792d431d70c0382771","incomingViewKey":"a2e084ee5410271827bc7300bfaa961c319ef91f28eae9bbf365174a63263701","outgoingViewKey":"90a290fc4f13c6f54f820d1233256721f28300c34f145a1fde1d51b732e14e76","publicAddress":"0c1896d84d73d221501bbd5b8d7e9b4218dce21a25d473567ba3e645cef686cd","createdAt":null,"multisigKeys":{"publicKeyPackage":"00c3d2051e03e747062ea420e09f09cfc67c3212b89e6920ea6b95ffad30d5d2ef006ff70506c02c61cf0bade9c6f5bfe68fd3c0057f5feadf60ca609eff1a0fb37178e78100b393bd4ada9bbb54d95e2a5e36b4fd21d1a1e51beebe19b7a277c89f7bb8900626be70604f4a6bd6de06007a7f934d7d8d64ece23c368c653baf4236ffbd9d35f461cbaacc835efd1d1330140b1cfeffc60c0a6c007b82b255d9f8b3f5cdf20d39e9ae31bffc51692792770c8efd890803948cf3206a30569c8b10f9cbc46ddc37643a564836f46215930fed8493cf3ea11ed1efb13a498e5eaf51f332459d0c","identifier":"f461cbaacc835efd1d1330140b1cfeffc60c0a6c007b82b255d9f8b3f5cdf20d","keyPackage":"00c3d2051ef461cbaacc835efd1d1330140b1cfeffc60c0a6c007b82b255d9f8b3f5cdf20d42710a36e332d4ba00572b1ef461a73de816c6765d830e1a366eb0795b6edc0c39e9ae31bffc51692792770c8efd890803948cf3206a30569c8b10f9cbc46ddc37643a564836f46215930fed8493cf3ea11ed1efb13a498e5eaf51f332459d0c02"},"proofAuthorizingKey":"82f7e8799d53851c6eb446dc1b05b47b54e48187b607c96c61fa6333c0517607"}
{"version":4,"name":"multisig-test-0","spendingKey":null,"viewKey":"24bf7639a6a251c3ea5a1a2083370a861066692627a0417b648052f71402ab214f2b3bee707e1b55bbec15358b2a37099b8bbcdbf8a502f89953a6ab04683b5b","incomingViewKey":"35eb8213299467e1e790f718da8db415427dd0579b567ae45bb4c2107c34ab00","outgoingViewKey":"3988bbb2ca281da03964cef01ffb85f143d9731e17ee4d3010ec08d17659f831","publicAddress":"84f6b03344cf493b4c54966c9ce91023a766148452a6737e04b2d3b4b8d580c5","createdAt":{"hash":"00000004c9c043422c9d9787c2e1a56433ae8760019a2a8d479d42bfd1f83fe7","sequence":192885},"multisigKeys":{"publicKeyPackage":"a600000000c3d2051e0221752510c8264b10bcc513400f2e6986635f8da4f0a5fe30f2cdd544a4ad99090e3a00e8307d803ddd893fe34213e7286eb3f57a5c4d19eff8a18ca95625ecc44fd9b805dbb0883dc26232b4a62493830fb0ca8751053bfaadedfc5c2c7a130a6e67fedac991705bb238f76fc09ab3ddc52ced3268cfd23dd08b844b8b8da69924bf7639a6a251c3ea5a1a2083370a861066692627a0417b648052f71402ab210200000072f2ee7ed629f6218fd67861b08304700cf4d39cd05e02c390dcca75193dd8f0e60db653d41b09fa4ad835c4199f209cec5f29b748da0d69a75c7bc78673f89f2ace80a541a41ca24a2c72bf6d80f0d91083622b4fd583b2b53fbba1afb1919b5af3c106901166de394efa8344591a5d2af4314b787ef0f891642fea79c0c5d304726e9d93a2da40afcf70a60149f81ff321cfbdd9f4bbeecca5c19f07ef2c515315a28a46e68cd0f4a00da076b391ad9cee4a59a9bcd5658113891e889211ff2b441c1127696fe457f97fec0ec5f550cc517d21ae9c05ac7dc91c2f8402a42012f27f222259d98a2488a01d2b1b15724b2179bc2e1d245b7286b58d698cc0950809","identity":"726e9d93a2da40afcf70a60149f81ff321cfbdd9f4bbeecca5c19f07ef2c515315a28a46e68cd0f4a00da076b391ad9cee4a59a9bcd5658113891e889211ff2b441c1127696fe457f97fec0ec5f550cc517d21ae9c05ac7dc91c2f8402a42012f27f222259d98a2488a01d2b1b15724b2179bc2e1d245b7286b58d698cc0950809","keyPackage":"00c3d2051e4fd9b805dbb0883dc26232b4a62493830fb0ca8751053bfaadedfc5c2c7a130ab9ee2d6bdad038ec917cff11d60d47c70fe587ba344691fc4e667b7fcbb054086e67fedac991705bb238f76fc09ab3ddc52ced3268cfd23dd08b844b8b8da69924bf7639a6a251c3ea5a1a2083370a861066692627a0417b648052f71402ab2102"},"proofAuthorizingKey":"efc774fbe4e198d3358f59a960752ef3774dc2fa8f94ffdfc4e2c06dc4512b0e"}
16 changes: 5 additions & 11 deletions ironfish/src/rpc/routes/wallet/exportAccount.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

import { generateKey } from '@ironfish/rust-nodejs'
import { v4 as uuid } from 'uuid'
import { useAccountFixture } from '../../../testUtilities'
import { createTrustedDealerKeyPackages, useAccountFixture } from '../../../testUtilities'
import { createRouteTest } from '../../../testUtilities/routeTest'
import { Account } from '../../../wallet'
import { Base64JsonEncoder } from '../../../wallet/account/encoder/base64json'
Expand Down Expand Up @@ -144,24 +143,19 @@ describe('Route wallet/exportAccount', () => {
})

it('should export an account with multisigKeys', async () => {
const key = generateKey()
const trustedDealerPackages = createTrustedDealerKeyPackages()

const accountName = 'foo'
const accountImport = {
name: accountName,
viewKey: key.viewKey,
spendingKey: null,
publicAddress: key.publicAddress,
incomingViewKey: key.incomingViewKey,
outgoingViewKey: key.outgoingViewKey,
version: 1,
createdAt: null,
...trustedDealerPackages,
multisigKeys: {
publicKeyPackage: 'aaaa',
identity: 'aaaa',
keyPackage: 'bbbb',
...trustedDealerPackages.keyPackages[0],
publicKeyPackage: trustedDealerPackages.publicKeyPackage,
},
proofAuthorizingKey: key.proofAuthorizingKey,
}

await routeTest.wallet.importAccount({ ...accountImport, id: uuid() })
Expand Down
13 changes: 5 additions & 8 deletions ironfish/src/rpc/routes/wallet/importAccount.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import { generateKey, LanguageCode, spendingKeyToWords } from '@ironfish/rust-nodejs'
import fs from 'fs'
import path from 'path'
import { createTrustedDealerKeyPackages } from '../../../testUtilities'
import { createRouteTest } from '../../../testUtilities/routeTest'
import { encodeAccount } from '../../../wallet/account/encoder/account'
import { Bech32Encoder } from '../../../wallet/account/encoder/bech32'
Expand Down Expand Up @@ -50,24 +51,20 @@ describe('Route wallet/importAccount', () => {
})

it('should import a multisig account that has no spending key', async () => {
const key = generateKey()
const trustedDealerPackages = createTrustedDealerKeyPackages()

const accountName = 'multisig'
const response = await routeTest.client
.request<ImportResponse>('wallet/importAccount', {
account: {
name: accountName,
viewKey: key.viewKey,
spendingKey: null,
publicAddress: key.publicAddress,
incomingViewKey: key.incomingViewKey,
outgoingViewKey: key.outgoingViewKey,
version: 1,
createdAt: null,
...trustedDealerPackages,
multisigKeys: {
publicKeyPackage: 'aaaa',
identity: 'aaaa',
keyPackage: 'bbbb',
...trustedDealerPackages.keyPackages[0],
publicKeyPackage: trustedDealerPackages.publicKeyPackage,
},
},
rescan: false,
Expand Down
Loading

0 comments on commit 2578019

Please sign in to comment.