Skip to content

Commit f2204bc

Browse files
authored
Merge pull request #8 from XYOracleNetwork/feature/simplify-construction
Simplify Init
2 parents 1a1819b + 5264657 commit f2204bc

10 files changed

Lines changed: 147 additions & 73 deletions

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,17 @@
2727
"dependencies": {
2828
"@xylabs/assert": "5.0.61",
2929
"@xylabs/delay": "5.0.61",
30-
"@xylabs/typeof": "5.0.61",
3130
"@xylabs/tsconfig": "7.2.32",
31+
"@xylabs/typeof": "5.0.61",
3232
"@xyo-network/payload-builder": "5.2.24",
3333
"@xyo-network/wallet": "5.2.24",
34-
"@xyo-network/xl1-sdk": "~1.18.2",
34+
"@xyo-network/xl1-sdk": "1.18.2",
3535
"dotenv": "17.2.3"
3636
},
3737
"devDependencies": {
3838
"@types/node": "25.0.9",
3939
"@xylabs/eslint-config-flat": "7.2.32",
40+
"@xyo-network/account-model": "5.2.24",
4041
"@xyo-network/payload-model": "5.2.24",
4142
"@xyo-network/xl1-cli": "1.18.1",
4243
"eslint": "9.39.2",
@@ -58,4 +59,4 @@
5859
"publishConfig": {
5960
"access": "restricted"
6061
}
61-
}
62+
}

src/getGateway.ts

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
1-
import { assertEx } from '@xylabs/assert'
2-
import type { XyoConnection } from '@xyo-network/xl1-sdk'
1+
import { isDefined } from '@xylabs/typeof'
2+
import type { SimpleXyoSigner, XyoConnection } from '@xyo-network/xl1-sdk'
33
import {
4-
ADDRESS_INDEX,
5-
buildSimpleXyoSigner, generateXyoBaseWalletFromPhrase,
6-
SimpleXyoGatewayRunner, XyoConnectionMoniker,
4+
SimpleXyoGatewayRunner, XyoConnectionMoniker, XyoSignerMoniker,
75
} from '@xyo-network/xl1-sdk'
86

97
import { getLocator } from './getLocator.ts'
108

11-
export const getGateway = async (mnemonic?: string, rpcEndpoint = 'http://localhost:8080/rpc') => {
12-
// Load the account to use for the transaction
13-
const walletMnemonic = assertEx(process.env.XYO_WALLET_MNEMONIC ?? mnemonic, () => 'Unable to resolve mnemonic from environment variable or argument')
14-
const account = await (await generateXyoBaseWalletFromPhrase(walletMnemonic)).derivePath(ADDRESS_INDEX.XYO)
15-
console.log('Using account:', account.address)
9+
let gateway: SimpleXyoGatewayRunner | undefined
1610

17-
// Build the signer
18-
const signer = await buildSimpleXyoSigner({ account })
11+
export const getGateway = async () => {
12+
// If existing gateway, return it
13+
if (isDefined(gateway)) return gateway
1914

20-
// Get the provider locator
21-
const locator = await getLocator(rpcEndpoint)
15+
// Otherwise, build a new gateway
2216

23-
// Get the XyoConnection instance
17+
// Get locator
18+
const locator = await getLocator()
19+
20+
// Use locator to get connection and signer
2421
const connection = await locator.getInstance<XyoConnection>(XyoConnectionMoniker)
22+
const signer = await locator.getInstance<SimpleXyoSigner>(XyoSignerMoniker)
2523

26-
// Return a new SimpleXyoGatewayRunner instance
27-
return new SimpleXyoGatewayRunner(connection, signer)
24+
// Create gateway from connection and signer
25+
gateway = new SimpleXyoGatewayRunner(connection, signer)
26+
return gateway
2827
}

src/getLocator.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
import { isDefined } from '@xylabs/typeof'
2-
import type {
3-
ProviderFactoryLocator, RpcSchemaMap, TransportFactory,
4-
} from '@xyo-network/xl1-sdk'
5-
import { buildJsonRpcProviderLocator, HttpRpcTransport } from '@xyo-network/xl1-sdk'
2+
import type { ProviderFactoryLocator } from '@xyo-network/xl1-sdk'
3+
import { buildJsonRpcProviderLocator, SimpleXyoSigner } from '@xyo-network/xl1-sdk'
4+
5+
import { getSignerAccount } from './getSignerAccount.ts'
6+
import { getTransportFactory } from './getTransportFactory.ts'
67

78
let locator: ProviderFactoryLocator
89

9-
export const getLocator = async (rpcEndpoint = 'http://localhost:8080/rpc') => {
10+
export const getLocator = async () => {
11+
// If existing locator, return it
1012
if (isDefined(locator)) return locator
11-
// Determine the RPC endpoint to use for the chain connection
12-
const endpoint = process.env.XYO_CHAIN_RPC_URL ?? rpcEndpoint
13-
console.log('Using endpoint:', endpoint)
1413

15-
const transportFactory: TransportFactory = (schemas: RpcSchemaMap) => new HttpRpcTransport(endpoint, schemas)
14+
// Build a new locator
15+
const transportFactory = getTransportFactory()
1616
locator = await buildJsonRpcProviderLocator({ transportFactory })
17+
18+
// Register the signer with the locator
19+
const account = await getSignerAccount()
20+
locator.register(SimpleXyoSigner.factory<SimpleXyoSigner>(SimpleXyoSigner.dependencies, { account }))
21+
22+
// Return the locator
1723
return locator
1824
}

src/getRandomTransactionData.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { PayloadBuilder } from '@xyo-network/payload-builder'
2+
import type { Payload } from '@xyo-network/payload-model'
3+
import type { HashPayload } from '@xyo-network/xl1-sdk'
4+
5+
/**
6+
* Generates random data for a transaction.
7+
* @returns An object containing off-chain and on-chain data for the transaction.
8+
*/
9+
export const getRandomTransactionData = async () => {
10+
// Data to store off-chain
11+
const salt = `Hello from Sample - ${new Date().toISOString()}`
12+
const idPayload: Payload<{ salt: string }> = { schema: 'network.xyo.id', salt }
13+
14+
// Data to store on-chain (can reference the off-chain data)
15+
const hash = await PayloadBuilder.hash(idPayload)
16+
const hashPayload: HashPayload = { schema: 'network.xyo.hash', hash }
17+
18+
return {
19+
offChainData: [idPayload],
20+
onChainData: [hashPayload],
21+
}
22+
}

src/getRpcUrl.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { config } from 'dotenv'
2+
3+
// Load environment variables from .env file
4+
config({ quiet: true })
5+
6+
/**
7+
* Gets the rpcUrl to use for interacting with the chain
8+
* @returns The rpcUrl to use for interacting with the chain
9+
*/
10+
export const getRpcUrl = (): string => process.env.XYO_CHAIN_RPC_URL ?? 'http://localhost:8080/rpc'

src/getSignerAccount.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { isDefined } from '@xylabs/typeof'
2+
import type { AccountInstance } from '@xyo-network/account-model'
3+
import { ADDRESS_INDEX, generateXyoBaseWalletFromPhrase } from '@xyo-network/xl1-sdk'
4+
5+
import { getWalletMnemonic } from './getWalletMnemonic.ts'
6+
7+
let signerAccount: AccountInstance | undefined
8+
9+
/**
10+
* Retrieves the signer account derived from the configured mnemonic.
11+
* @returns The derived account
12+
*/
13+
export const getSignerAccount = async () => {
14+
// If existing signer account, return it
15+
if (isDefined (signerAccount)) return signerAccount
16+
17+
// Create new signer account
18+
const walletMnemonic = getWalletMnemonic()
19+
const wallet = await generateXyoBaseWalletFromPhrase(walletMnemonic)
20+
signerAccount = await wallet.derivePath(ADDRESS_INDEX.XYO)
21+
console.log('Using signer account:', signerAccount.address)
22+
return signerAccount
23+
}

src/getTransportFactory.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { isDefined } from '@xylabs/typeof'
2+
import type { RpcSchemaMap, TransportFactory } from '@xyo-network/xl1-sdk'
3+
import { HttpRpcTransport } from '@xyo-network/xl1-sdk'
4+
5+
import { getRpcUrl } from './getRpcUrl.ts'
6+
7+
let transportFactory: TransportFactory | undefined
8+
9+
/**
10+
* Retrieves a transport factory for the configured RPC URL.
11+
* @returns A transport factory for the configured RPC URL
12+
*/
13+
export const getTransportFactory = () => {
14+
// If existing transport factory, return it
15+
if (isDefined(transportFactory)) return transportFactory
16+
17+
// Build a new transport factory
18+
const rpcUrl = getRpcUrl()
19+
console.log('Using rpcUrl:', rpcUrl)
20+
transportFactory = (schemas: RpcSchemaMap) => new HttpRpcTransport(rpcUrl, schemas)
21+
return transportFactory
22+
}

src/getWalletMnemonic.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { HDWallet } from '@xyo-network/wallet'
2+
import { config } from 'dotenv'
3+
4+
// Load environment variables from .env file
5+
config({ quiet: true })
6+
7+
// Parse the relevant ENV VARs or use defaults
8+
const mnemonic = process.env.XYO_WALLET_MNEMONIC ?? HDWallet.generateMnemonic()
9+
10+
/**
11+
* Gets the mnemonic to use for the wallet
12+
* @returns The mnemonic to use for the wallet
13+
*/
14+
export const getWalletMnemonic = (): string => mnemonic

src/helloWorld.ts

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
import { isError } from '@xylabs/typeof'
2-
import { PayloadBuilder } from '@xyo-network/payload-builder'
3-
import type { Payload } from '@xyo-network/payload-model'
4-
import type { HashPayload, SignedHydratedTransaction } from '@xyo-network/xl1-protocol'
5-
import { config } from 'dotenv'
2+
import type { SignedHydratedTransaction } from '@xyo-network/xl1-protocol'
63

74
import { getGateway } from './getGateway.ts'
5+
import { getRandomTransactionData } from './getRandomTransactionData.ts'
86

9-
// Load environment variables from .env file
10-
config({ quiet: true })
11-
7+
// Log to console
128
const logger = console
139

14-
export async function helloWorld(mnemonic?: string): Promise<void> {
10+
/**
11+
* Runs a simple "Hello World" transaction on the XL1 network.
12+
*/
13+
export async function helloWorld(): Promise<void> {
1514
try {
1615
console.log('\n**** Starting XL1 Hello World NodeJs Sample ****\n')
1716

1817
// Generate random data to send in the transaction
1918
const { onChainData, offChainData } = await getRandomTransactionData()
2019

21-
const gateway = await getGateway(mnemonic)
20+
// Get gateway to interact with the chain
21+
const gateway = await getGateway()
2222

2323
// Send the transaction to the network
2424
const [txHash] = await gateway.addPayloadsToChain(onChainData, offChainData)
@@ -37,22 +37,3 @@ const logSuccess = (_tx: SignedHydratedTransaction) => {
3737
console.log('1. Install the XYO Layer One Wallet from https://chromewebstore.google.com/detail/xl1-wallet/fblbagcjeigmhakkfgjpdlcapcgmcfbm')
3838
console.log('2. In that same browser, go to: https://explore.xyo.network/xl1/local/')
3939
}
40-
41-
/**
42-
* Generates random data for a transaction.
43-
* @returns An object containing off-chain and on-chain data for the transaction.
44-
*/
45-
const getRandomTransactionData = async () => {
46-
// Data to store off-chain
47-
const salt = `Hello from Sample - ${new Date().toISOString()}`
48-
const idPayload: Payload<{ salt: string }> = { schema: 'network.xyo.id', salt }
49-
50-
// Data to store on-chain (can reference the off-chain data)
51-
const hash = await PayloadBuilder.hash(idPayload)
52-
const hashPayload: HashPayload = { schema: 'network.xyo.hash', hash }
53-
54-
return {
55-
offChainData: [idPayload],
56-
onChainData: [hashPayload],
57-
}
58-
}

src/helloWorldRunner.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import { type ChildProcess, spawn } from 'node:child_process'
22

3-
import { HDWallet } from '@xyo-network/wallet'
43
import type { XyoViewer } from '@xyo-network/xl1-protocol-sdk'
5-
import {
6-
ADDRESS_INDEX, generateXyoBaseWalletFromPhrase, XyoViewerMoniker,
7-
} from '@xyo-network/xl1-protocol-sdk'
4+
import { XyoViewerMoniker } from '@xyo-network/xl1-protocol-sdk'
85

96
import { getLocator } from './getLocator.ts'
7+
import { getSignerAccount } from './getSignerAccount.ts'
8+
import { getWalletMnemonic } from './getWalletMnemonic.ts'
109
import { helloWorld } from './helloWorld.js'
1110
import { waitForInitialBlocks } from './waitForInitialBlocks.js'
1211

12+
// Parse the relevant ENV VARs or use defaults
13+
const mnemonic = getWalletMnemonic()
14+
1315
/**
1416
* Starts the XL1 node using command in a child process
1517
* The child process will be terminated when the parent process exits
@@ -18,8 +20,6 @@ import { waitForInitialBlocks } from './waitForInitialBlocks.js'
1820
async function startXl1(): Promise<string> {
1921
console.log('Starting XL1...')
2022

21-
const mnemonic = process.env.XYO_WALLET_MNEMONIC ?? HDWallet.generateMnemonic()
22-
2323
// Track the child process
2424
let xl1Process: ChildProcess | null = null
2525

@@ -49,12 +49,10 @@ async function startXl1(): Promise<string> {
4949
})
5050

5151
try {
52-
// log out the mnemonic and wallet address using same steps as producer
53-
const wallet = await generateXyoBaseWalletFromPhrase(mnemonic)
54-
const account = await wallet.derivePath(ADDRESS_INDEX.XYO)
55-
56-
console.log('Generated mnemonic:', mnemonic)
57-
console.log('Producer Wallet address:', account.address)
52+
// Log out the mnemonic and signer address in case random was generated
53+
const account = await getSignerAccount()
54+
console.log('Using signer mnemonic:', mnemonic)
55+
console.log('Using producer address:', account.address)
5856

5957
// Spawn the XL1 process
6058
xl1Process = spawn('node', ['./node_modules/@xyo-network/xl1-cli/scripts/xl1.mjs', '--logLevel="warn"', '--producer.mnemonic', JSON.stringify(mnemonic)], {
@@ -101,10 +99,8 @@ async function startXl1(): Promise<string> {
10199
}
102100
}
103101

104-
let mnemonic: string
105-
106102
try {
107-
mnemonic = await startXl1()
103+
await startXl1()
108104
} catch (ex) {
109105
console.error('Failed to start XL1:', ex)
110106
// eslint-disable-next-line unicorn/no-process-exit
@@ -114,7 +110,7 @@ try {
114110
console.log('XL1 is ready, starting sample...')
115111

116112
try {
117-
await helloWorld(mnemonic)
113+
await helloWorld()
118114
} catch (error) {
119115
console.error('Error importing application:', error)
120116
}

0 commit comments

Comments
 (0)