Skip to content

Commit 4e6365e

Browse files
committed
Reorg, cleanup Setup, SetupClient
1 parent 1c313cf commit 4e6365e

File tree

5 files changed

+125
-110
lines changed

5 files changed

+125
-110
lines changed

src/Setup.ts

Lines changed: 27 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,17 @@
11
import {
2-
Beef,
3-
CreateActionArgs,
4-
CreateActionOutput,
5-
CreateActionResult,
62
KeyDeriver,
7-
P2PKH,
83
PrivateKey,
9-
PublicKey,
10-
SignActionArgs,
11-
SignActionResult,
12-
WalletInterface
134
} from '@bsv/sdk'
145
import {
156
Monitor,
167
sdk,
178
Services,
189
SetupClient,
19-
StorageClient,
20-
verifyTruthy,
2110
Wallet,
2211
WalletStorageManager
2312
} from './index.client'
24-
import { PrivilegedKeyManager } from './sdk'
2513
import { Knex, knex as makeKnex } from 'knex'
26-
import { SetupWallet, StorageKnex } from './index.all'
14+
import { SetupWallet, SetupWalletArgs, StorageKnex } from './index.all'
2715

2816
/**
2917
* The 'Setup` class provides static setup functions to construct BRC-100 compatible
@@ -48,18 +36,10 @@ export abstract class Setup extends SetupClient {
4836
*
4937
* @publicbody
5038
*/
51-
static async createKnexWallet(args: {
52-
knex: Knex<any, any[]>
53-
databaseName: string
54-
chain?: sdk.Chain
55-
rootKeyHex?: string
56-
privKeyHex?: string
57-
}): Promise<SetupWallet> {
58-
const wo = await Setup.createWalletOnly({
59-
chain: args.chain,
60-
rootKeyHex: args.rootKeyHex,
61-
privKeyHex: args.privKeyHex
62-
})
39+
static async createKnexWallet(
40+
args: SetupWalletKnexArgs
41+
): Promise<SetupWalletKnex> {
42+
const wo = await Setup.createWallet(args)
6343
const activeStorage = new StorageKnex({
6444
chain: wo.chain,
6545
knex: args.knex,
@@ -72,7 +52,7 @@ export abstract class Setup extends SetupClient {
7252
await wo.storage.addWalletStorageProvider(activeStorage)
7353
const { user, isNew } = await activeStorage.findOrInsertUser(wo.identityKey)
7454
const userId = user.userId
75-
const r: SetupWallet = {
55+
const r: SetupWalletKnex = {
7656
...wo,
7757
activeStorage,
7858
userId
@@ -105,33 +85,39 @@ export abstract class Setup extends SetupClient {
10585
return knex
10686
}
10787

108-
static async createMySQLWallet(args: {
109-
databaseName: string
110-
chain?: sdk.Chain
111-
rootKeyHex?: string
112-
privKeyHex?: string
113-
}): Promise<SetupWallet> {
114-
const env = Setup.getEnv(args.chain || 'test')
88+
static async createMySQLWallet(
89+
args: SetupWalletMySQLArgs
90+
): Promise<SetupWalletKnex> {
11591
return await this.createKnexWallet({
11692
...args,
117-
knex: Setup.createMySQLKnex(env.mySQLConnection, args.databaseName)
93+
knex: Setup.createMySQLKnex(args.env.mySQLConnection, args.databaseName)
11894
})
11995
}
12096

121-
static async createSQLiteWallet(args: {
122-
filePath: string
123-
databaseName: string
124-
chain?: sdk.Chain
125-
rootKeyHex?: string
126-
privKeyHex?: string
127-
}): Promise<SetupWallet> {
97+
static async createSQLiteWallet(
98+
args: SetupWalletSQLiteArgs
99+
): Promise<SetupWalletKnex> {
128100
return await this.createKnexWallet({
129101
...args,
130102
knex: Setup.createSQLiteKnex(args.filePath)
131103
})
132104
}
133105
}
134106

107+
export interface SetupWalletKnexArgs extends SetupWalletArgs {
108+
knex: Knex<any, any[]>
109+
databaseName: string
110+
}
111+
112+
export interface SetupWalletMySQLArgs extends SetupWalletArgs {
113+
databaseName: string
114+
}
115+
116+
export interface SetupWalletSQLiteArgs extends SetupWalletArgs {
117+
filePath: string
118+
databaseName: string
119+
}
120+
135121
export interface SetupWalletKnex extends SetupWallet {
136122
activeStorage: StorageKnex
137123
userId: number

src/SetupClient.ts

Lines changed: 73 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
BEEF,
23
Beef,
34
CreateActionArgs,
45
CreateActionOptions,
@@ -10,6 +11,8 @@ import {
1011
PublicKey,
1112
SignActionArgs,
1213
SignActionResult,
14+
Transaction,
15+
UnlockingScript,
1316
WalletInterface
1417
} from '@bsv/sdk'
1518
import {
@@ -88,14 +91,6 @@ export abstract class SetupClient {
8891
*/
8992
static getEnv(chain: sdk.Chain): SetupEnv {
9093
// Identity keys of the lead maintainer of this repo...
91-
const mainTaalApiKey = verifyTruthy(
92-
process.env.MAIN_TAAL_API_KEY || '',
93-
`.env value for 'mainTaalApiKey' is required.`
94-
)
95-
const testTaalApiKey = verifyTruthy(
96-
process.env.TEST_TAAL_API_KEY || '',
97-
`.env value for 'testTaalApiKey' is required.`
98-
)
9994
const identityKey =
10095
chain === 'main'
10196
? process.env.MY_MAIN_IDENTITY
@@ -106,6 +101,12 @@ export abstract class SetupClient {
106101
: process.env.MY_TEST_IDENTITY2
107102
const DEV_KEYS = process.env.DEV_KEYS || '{}'
108103
const mySQLConnection = process.env.MYSQL_CONNECTION || '{}'
104+
const taalApiKey =
105+
verifyTruthy(chain === 'main'
106+
? process.env.MAIN_TAAL_API_KEY
107+
: process.env.TEST_TAAL_API_KEY,
108+
`.env value for '${chain.toUpperCase()}_TAAL_API_KEY' is required.`
109+
)
109110

110111
if (!identityKey || !identityKey2)
111112
throw new sdk.WERR_INVALID_OPERATION(
@@ -116,8 +117,7 @@ export abstract class SetupClient {
116117
chain,
117118
identityKey,
118119
identityKey2,
119-
mainTaalApiKey,
120-
testTaalApiKey,
120+
taalApiKey,
121121
devKeys: JSON.parse(DEV_KEYS) as Record<string, string>,
122122
mySQLConnection
123123
}
@@ -143,7 +143,9 @@ export abstract class SetupClient {
143143
args.active,
144144
args.backups
145145
)
146-
if (storage.stores.length > 0) await storage.makeAvailable()
146+
if (storage.stores.length > 0) await storage.makeAvailable();
147+
const serviceOptions = Services.createDefaultOptions(chain)
148+
serviceOptions.taalApiKey = args.env.taalApiKey
147149
const services = new Services(args.chain)
148150
const monopts = Monitor.createDefaultWalletMonitorOptions(
149151
chain,
@@ -178,20 +180,55 @@ export abstract class SetupClient {
178180
return r
179181
}
180182

181-
static async createWalletWithStorageClient(args: SetupWalletClientArgs)
182-
: Promise<SetupWalletClient>
183-
{
184-
const wo = await Setup.createWallet(args)
185-
if (wo.chain === 'main') throw new sdk.WERR_INVALID_PARAMETER('chain', `'test' for now, 'main' is not yet supported.`);
183+
static async createWalletWithStorageClient(
184+
args: SetupWalletClientArgs
185+
): Promise<SetupWalletClient> {
186+
const wo = await Setup.createWallet(args)
187+
if (wo.chain === 'main')
188+
throw new sdk.WERR_INVALID_PARAMETER(
189+
'chain',
190+
`'test' for now, 'main' is not yet supported.`
191+
)
186192

187-
const endpointUrl = args.endpointUrl || 'https://staging-dojo.babbage.systems'
188-
const client = new StorageClient(wo.wallet, endpointUrl)
189-
await wo.storage.addWalletStorageProvider(client)
190-
await wo.storage.makeAvailable()
191-
return {
192-
...wo,
193-
endpointUrl
194-
}
193+
const endpointUrl =
194+
args.endpointUrl || 'https://staging-dojo.babbage.systems'
195+
const client = new StorageClient(wo.wallet, endpointUrl)
196+
await wo.storage.addWalletStorageProvider(client)
197+
await wo.storage.makeAvailable()
198+
return {
199+
...wo,
200+
endpointUrl
201+
}
202+
}
203+
204+
static getKeyPair(priv?: string | PrivateKey): KeyPairAddress {
205+
if (priv === undefined) priv = PrivateKey.fromRandom()
206+
else if (typeof priv === 'string') priv = new PrivateKey(priv, 'hex')
207+
208+
const pub = PublicKey.fromPrivateKey(priv)
209+
const address = pub.toAddress()
210+
return { privateKey: priv, publicKey: pub, address }
211+
}
212+
213+
static getLockP2PKH(address: string) {
214+
const p2pkh = new P2PKH()
215+
const lock = p2pkh.lock(address)
216+
return lock
217+
}
218+
219+
static getUnlockP2PKH(
220+
priv: PrivateKey,
221+
satoshis: number
222+
): sdk.ScriptTemplateUnlock {
223+
const p2pkh = new P2PKH()
224+
const lock = Setup.getLockP2PKH(Setup.getKeyPair(priv).address)
225+
// Prepare to pay with SIGHASH_ALL and without ANYONE_CAN_PAY.
226+
// In otherwords:
227+
// - all outputs must remain in the current order, amount and locking scripts.
228+
// - all inputs must remain from the current outpoints and sequence numbers.
229+
// (unlock scripts are never signed)
230+
const unlock = p2pkh.unlock(priv, 'all', false, satoshis, lock)
231+
return unlock
195232
}
196233

197234
static createP2PKHOutputs(
@@ -255,36 +292,13 @@ export abstract class SetupClient {
255292
return { cr, outpoints }
256293
}
257294

258-
/**
259-
* TODO...
260-
*/
261-
static async internalizeP2PKHOutpoints() {}
262-
263-
static getKeyPair(priv?: string | PrivateKey): KeyPairAddress {
264-
if (priv === undefined) priv = PrivateKey.fromRandom()
265-
else if (typeof priv === 'string') priv = new PrivateKey(priv, 'hex')
266-
267-
const pub = PublicKey.fromPrivateKey(priv)
268-
const address = pub.toAddress()
269-
return { privateKey: priv, publicKey: pub, address }
270-
}
271-
272-
static getLockP2PKH(address: string) {
273-
const p2pkh = new P2PKH()
274-
const lock = p2pkh.lock(address)
275-
return lock
276-
}
277-
278-
static getUnlockP2PKH(priv: PrivateKey, satoshis: number) {
279-
const p2pkh = new P2PKH()
280-
const lock = Setup.getLockP2PKH(Setup.getKeyPair(priv).address)
281-
// Prepare to pay with SIGHASH_ALL and without ANYONE_CAN_PAY.
282-
// In otherwords:
283-
// - all outputs must remain in the current order, amount and locking scripts.
284-
// - all inputs must remain from the current outpoints and sequence numbers.
285-
// (unlock scripts are never signed)
286-
const unlock = p2pkh.unlock(priv, 'all', false, satoshis, lock)
287-
return unlock
295+
static async fundWalletFromP2PKHOutpoints(
296+
wallet: WalletInterface,
297+
outpoints: string[],
298+
p2pkhKey: KeyPairAddress,
299+
inputBEEF?: BEEF
300+
) {
301+
// TODO
288302
}
289303
}
290304

@@ -303,15 +317,14 @@ export interface SetupEnv {
303317
chain: sdk.Chain
304318
identityKey: string
305319
identityKey2: string
306-
mainTaalApiKey: string
307-
testTaalApiKey: string
320+
taalApiKey: string
308321
devKeys: Record<string, string>
309322
mySQLConnection: string
310323
}
311324

312325
/**
313326
* Arguments used to construct a `Wallet`
314-
*
327+
*
315328
* @param env Configuration "secrets" typically obtained by `Setup.makeEnv` and `Setup.getEnv` functions.
316329
* @param chain Optional. Which chain this wallet is on: 'main' or 'test'.
317330
* Defaults to `env.chain`.
@@ -343,9 +356,9 @@ export interface SetupWallet {
343356
}
344357

345358
export interface SetupWalletClientArgs extends SetupWalletArgs {
346-
endpointUrl?: string
359+
endpointUrl?: string
347360
}
348361

349362
export interface SetupWalletClient extends SetupWallet {
350-
endpointUrl: string
351-
}
363+
endpointUrl: string
364+
}

src/index.all.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
export * as sdk from './sdk/index'
22
export * from './utility/index.all'
33
export * from './Wallet'
4-
export * from './SetupClient'
4+
export {
5+
SetupClient,
6+
KeyPairAddress,
7+
SetupEnv,
8+
SetupWalletArgs,
9+
SetupWallet,
10+
SetupWalletClient,
11+
SetupWalletClientArgs
12+
} from './SetupClient'
513
export * from './Setup'
614
export * from './signer/WalletSigner'
715
export * from './storage/index.all'

src/sdk/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Transaction, UnlockingScript } from '@bsv/sdk'
2+
13
/**
24
* Identifies a unique transaction output by its `txid` and index `vout`
35
*/
@@ -113,3 +115,8 @@ export interface EntityTimeStamp {
113115
created_at: Date
114116
updated_at: Date
115117
}
118+
119+
export interface ScriptTemplateUnlock {
120+
sign: (tx: Transaction, inputIndex: number) => Promise<UnlockingScript>
121+
estimateLength: (tx: Transaction, inputIndex: number) => Promise<number>
122+
}

test/examples/README.man.test.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
import { InternalizeActionArgs, PrivateKey, Utils } from '@bsv/sdk'
22
import { Setup } from '../../src'
33

4-
describe.skip('examples README tests', () => {
4+
describe('examples README tests', () => {
55
jest.setTimeout(99999999)
66

7-
it('0', async () => {
8-
const rootKeyHex = PrivateKey.fromRandom().toString()
9-
console.log(
10-
`MAKE A SECURE COPY OF YOUR WALLET PRIVATE ROOT KEY: ${rootKeyHex}`
11-
)
7+
it('0 makeEnv', async () => {
8+
const envString = Setup.makeEnv()
9+
})
10+
11+
it('1 internalize wallet payment', async () => {
12+
13+
const env = Setup.getEnv('test')
1214

1315
const { wallet } = await Setup.createSQLiteWallet({
16+
env,
1417
filePath: './myTestWallet.sqlite',
1518
databaseName: 'myTestWallet',
16-
chain: 'test',
17-
rootKeyHex
1819
})
1920

2021
// Obtain a Wallet Payment for your new wallet from a testnet funding faucet.

0 commit comments

Comments
 (0)