Skip to content

Commit 83c9078

Browse files
authored
Merge pull request #4752 from iron-fish/staging
Staging -> Master
2 parents 4fab80d + c979262 commit 83c9078

File tree

173 files changed

+7372
-2759
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

173 files changed

+7372
-2759
lines changed

Cargo.lock

Lines changed: 11 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ironfish-cli/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ironfish",
3-
"version": "1.19.0",
3+
"version": "1.20.0",
44
"description": "CLI for running and interacting with an Iron Fish node",
55
"author": "Iron Fish <[email protected]> (https://ironfish.network)",
66
"main": "build/src/index.js",
@@ -62,8 +62,8 @@
6262
"@aws-sdk/client-s3": "3",
6363
"@aws-sdk/client-secrets-manager": "3",
6464
"@aws-sdk/s3-request-presigner": "3",
65-
"@ironfish/rust-nodejs": "1.16.0",
66-
"@ironfish/sdk": "1.19.0",
65+
"@ironfish/rust-nodejs": "1.17.0",
66+
"@ironfish/sdk": "1.20.0",
6767
"@oclif/core": "1.23.1",
6868
"@oclif/plugin-help": "5.1.12",
6969
"@oclif/plugin-not-found": "2.3.1",

ironfish-cli/src/commands/wallet/export.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export class ExportCommand extends IronfishCommand {
6565
? AccountFormat.Mnemonic
6666
: flags.json
6767
? AccountFormat.JSON
68-
: AccountFormat.Bech32
68+
: AccountFormat.Base64Json
6969

7070
const client = await this.sdk.connectRpc(local)
7171
const response = await client.wallet.exportAccount({

ironfish-cli/src/commands/wallet/import.ts

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
/* This Source Code Form is subject to the terms of the Mozilla Public
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4-
import { PromiseUtils } from '@ironfish/sdk'
4+
import { PromiseUtils, RPC_ERROR_CODES, RpcRequestError } from '@ironfish/sdk'
55
import { CliUx, Flags } from '@oclif/core'
66
import { IronfishCommand } from '../../command'
77
import { RemoteFlags } from '../../flags'
8+
import { longPrompt } from '../../utils/longPrompt'
89

910
export class ImportCommand extends IronfishCommand {
1011
static description = `Import an account`
@@ -78,11 +79,40 @@ export class ImportCommand extends IronfishCommand {
7879
flags.name = name
7980
}
8081

81-
const result = await client.wallet.importAccount({
82-
account,
83-
rescan: flags.rescan,
84-
name: flags.name,
85-
})
82+
let result
83+
84+
while (!result) {
85+
try {
86+
result = await client.wallet.importAccount({
87+
account,
88+
rescan: flags.rescan,
89+
name: flags.name,
90+
})
91+
} catch (e) {
92+
if (
93+
e instanceof RpcRequestError &&
94+
(e.code === RPC_ERROR_CODES.DUPLICATE_ACCOUNT_NAME.toString() ||
95+
e.code === RPC_ERROR_CODES.IMPORT_ACCOUNT_NAME_REQUIRED.toString())
96+
) {
97+
if (e.code === RPC_ERROR_CODES.DUPLICATE_ACCOUNT_NAME.toString()) {
98+
this.log()
99+
this.log(e.codeMessage)
100+
}
101+
102+
const name = await CliUx.ux.prompt('Enter a name for the account', {
103+
required: true,
104+
})
105+
if (name === flags.name) {
106+
this.error(`Entered the same name: '${name}'`)
107+
}
108+
109+
flags.name = name
110+
continue
111+
}
112+
113+
throw e
114+
}
115+
}
86116

87117
const { name, isDefaultAccount } = result.content
88118
this.log(`Account ${name} imported.`)
@@ -120,13 +150,8 @@ export class ImportCommand extends IronfishCommand {
120150
}
121151

122152
async importTTY(): Promise<string> {
123-
const userInput = await CliUx.ux.prompt(
124-
'Paste the output of wallet:export, or your spending key',
125-
{
126-
required: true,
127-
},
128-
)
129-
130-
return userInput.trim()
153+
return await longPrompt('Paste the output of wallet:export, or your spending key: ', {
154+
required: true,
155+
})
131156
}
132157
}

ironfish-cli/src/commands/wallet/mint.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ export class Mint extends IronfishCommand {
193193
client: client,
194194
required: true,
195195
text: 'Enter the amount',
196-
minimum: 1n,
196+
minimum: 0n,
197197
logger: this.logger,
198198
})
199199
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4+
import { ACCOUNT_SCHEMA_VERSION, Base64JsonEncoder } from '@ironfish/sdk'
5+
import { CliUx, Flags } from '@oclif/core'
6+
import { IronfishCommand } from '../../../../command'
7+
import { RemoteFlags } from '../../../../flags'
8+
9+
export class MultisigCreate extends IronfishCommand {
10+
static description = `Create a set of multisig accounts from identities`
11+
static hidden = true
12+
13+
static flags = {
14+
...RemoteFlags,
15+
name: Flags.string({
16+
char: 'n',
17+
description: 'Name to use for the coordinator',
18+
}),
19+
identity: Flags.string({
20+
char: 'i',
21+
description: 'Identity of a participant',
22+
multiple: true,
23+
}),
24+
minSigners: Flags.integer({
25+
char: 'm',
26+
description: 'Minimum number of signers to meet signing threshold',
27+
}),
28+
importCoordinator: Flags.boolean({
29+
char: 'c',
30+
default: true,
31+
description: 'Import the coordinator as a view-only account after creating key packages',
32+
}),
33+
}
34+
35+
async start(): Promise<void> {
36+
const { flags } = await this.parse(MultisigCreate)
37+
38+
let identities = flags.identity
39+
if (!identities || identities.length < 2) {
40+
const input = await CliUx.ux.prompt('Enter the identities separated by commas', {
41+
required: true,
42+
})
43+
identities = input.split(',')
44+
45+
if (identities.length < 2) {
46+
this.error('Minimum number of identities must be at least 2')
47+
}
48+
}
49+
identities = identities.map((i) => i.trim())
50+
51+
let minSigners = flags.minSigners
52+
if (!minSigners) {
53+
const input = await CliUx.ux.prompt('Enter the number of minimum signers', {
54+
required: true,
55+
})
56+
minSigners = parseInt(input)
57+
if (isNaN(minSigners) || minSigners < 2) {
58+
this.error('Minimum number of signers must be at least 2')
59+
}
60+
}
61+
62+
const name =
63+
flags.name?.trim() ??
64+
(await CliUx.ux.prompt('Enter the name for the coordinator', { required: true }))
65+
66+
const client = await this.sdk.connectRpc()
67+
68+
const response = await client.wallet.multisig.createTrustedDealerKeyPackage({
69+
minSigners,
70+
participants: identities.map((identity) => ({ identity })),
71+
})
72+
73+
const chainResponse = await client.chain.getChainInfo()
74+
const hash = Buffer.from(chainResponse.content.currentBlockIdentifier.hash, 'hex')
75+
const sequence = Number(chainResponse.content.currentBlockIdentifier.index)
76+
const createdAt = {
77+
hash,
78+
sequence,
79+
}
80+
81+
if (flags.importCoordinator) {
82+
this.log()
83+
CliUx.ux.action.start('Importing the coordinator as a view-only account')
84+
85+
await client.wallet.importAccount({
86+
account: {
87+
name,
88+
version: ACCOUNT_SCHEMA_VERSION,
89+
createdAt: {
90+
hash: createdAt.hash.toString('hex'),
91+
sequence: createdAt.sequence,
92+
},
93+
spendingKey: null,
94+
viewKey: response.content.viewKey,
95+
incomingViewKey: response.content.incomingViewKey,
96+
outgoingViewKey: response.content.outgoingViewKey,
97+
publicAddress: response.content.publicAddress,
98+
proofAuthorizingKey: response.content.proofAuthorizingKey,
99+
multisigKeys: {
100+
publicKeyPackage: response.content.publicKeyPackage,
101+
},
102+
},
103+
})
104+
105+
CliUx.ux.action.stop()
106+
}
107+
108+
const encoder = new Base64JsonEncoder()
109+
110+
for (const [i, keyPackage] of response.content.keyPackages.entries()) {
111+
this.log('\n')
112+
this.log(`Account ${i + 1}`)
113+
this.log(`Identity ${keyPackage.identity}`)
114+
this.log('----------------')
115+
const accountStr = encoder.encode({
116+
name: `${name}-${i}`,
117+
version: ACCOUNT_SCHEMA_VERSION,
118+
createdAt,
119+
spendingKey: null,
120+
viewKey: response.content.viewKey,
121+
incomingViewKey: response.content.incomingViewKey,
122+
outgoingViewKey: response.content.outgoingViewKey,
123+
publicAddress: response.content.publicAddress,
124+
proofAuthorizingKey: response.content.proofAuthorizingKey,
125+
multisigKeys: {
126+
identity: keyPackage.identity,
127+
keyPackage: keyPackage.keyPackage,
128+
publicKeyPackage: response.content.publicKeyPackage,
129+
},
130+
})
131+
this.log(accountStr)
132+
}
133+
134+
this.log()
135+
}
136+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4+
5+
import { CliUx, Flags } from '@oclif/core'
6+
import { IronfishCommand } from '../../../command'
7+
import { RemoteFlags } from '../../../flags'
8+
import { longPrompt } from '../../../utils/longPrompt'
9+
10+
export class CreateSignatureShareCommand extends IronfishCommand {
11+
static description = `Creates a signature share for a participant for a given transaction`
12+
static hidden = true
13+
14+
static flags = {
15+
...RemoteFlags,
16+
account: Flags.string({
17+
char: 'f',
18+
description: 'The account from which the signature share will be created',
19+
required: false,
20+
}),
21+
signingPackage: Flags.string({
22+
char: 's',
23+
description: 'The signing package for which the signature share will be created',
24+
required: false,
25+
}),
26+
signerIdentity: Flags.string({
27+
char: 'i',
28+
description:
29+
'The identity of the participants that will sign the transaction (may be specified multiple times to add multiple signers)',
30+
required: true,
31+
multiple: true,
32+
}),
33+
confirm: Flags.boolean({
34+
default: false,
35+
description: 'Confirm creating signature share without confirming',
36+
}),
37+
}
38+
39+
async start(): Promise<void> {
40+
const { flags } = await this.parse(CreateSignatureShareCommand)
41+
let signingPackage = flags.signingPackage?.trim()
42+
43+
if (!signingPackage) {
44+
signingPackage = await longPrompt('Enter the signing package: ')
45+
}
46+
47+
if (!flags.confirm) {
48+
const confirmed = await CliUx.ux.confirm('Confirm new signature share creation (Y/N)')
49+
if (!confirmed) {
50+
this.error('Creating signature share aborted')
51+
}
52+
}
53+
54+
const client = await this.sdk.connectRpc()
55+
const signatureShareResponse = await client.wallet.multisig.createSignatureShare({
56+
account: flags.account,
57+
signingPackage,
58+
})
59+
60+
this.log('Signing Share:\n')
61+
this.log(signatureShareResponse.content.signatureShare)
62+
}
63+
}

0 commit comments

Comments
 (0)