Skip to content

Commit

Permalink
wip: BREAKING: refactor: move mocknet into @fadroma/scrt
Browse files Browse the repository at this point in the history
- time for v2 of @fadroma/agent and @hackbg/fadroma I guess
- gonna try to include other breaking changes here
  • Loading branch information
egasimus committed Oct 13, 2023
1 parent 7474db8 commit 85300fb
Show file tree
Hide file tree
Showing 17 changed files with 166 additions and 146 deletions.
1 change: 1 addition & 0 deletions agent/agent-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export * from '@hackbg/into'
export * from '@hackbg/hide'
export * from '@hackbg/many'
export * from '@hackbg/4mat'
export * from '@hackbg/dump'

export type Name = string

Expand Down
23 changes: 8 additions & 15 deletions agent/agent-chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import type {
Uploadable
} from './agent'
import { Error, Console, into, prop, hideProperties as hide, randomBytes } from './agent-base'
import type * as Mocknet from './agent-mocknet'

/** A chain can be in one of the following modes: */
export enum ChainMode {
Expand Down Expand Up @@ -207,22 +206,16 @@ export abstract class Chain {
}
/** @returns a devnet instance of this chain. */
static devnet (options: Partial<Chain> = {}): Chain {
return new (this as any)({
...options.devnet ? { id: options.devnet.chainId, url: options.devnet.url.toString() } : {},
...options,
mode: Chain.Mode.Devnet
})
options = { ...options, mode: Chain.Mode.Devnet }
if (options.devnet) {
options.id = options.devnet.chainId
options.url = options.devnet.url.toString()
}
return new (this as any)(options)
}
/** @returns a mocknet instance of this chain. */
static mocknet (options?: Partial<Mocknet.Chain>): Mocknet.Chain {
// this method is replaced in the root of the package
throw new Error('stub. try with `new Mocknet()`')
}
/** Async functions that return Chain instances in different modes.
* Values for `FADROMA_CHAIN` environment variable.
* Populated by @fadroma/connect. */
static variants: ChainRegistry = {
Mocknet: (...args) => this.mocknet(...args)
static mocknet (options?: Partial<Chain>): Chain {
throw new Error('Mocknet is not enabled for this chain.')
}
}
/** @returns the chain of a thing
Expand Down
8 changes: 4 additions & 4 deletions agent/agent-services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
import type {
Address, TxHash, ChainId, Agent, ClientClass, Hashed, CodeId, Deployment, Class, CodeHash,
Mocknet
Address, TxHash, ChainId, Agent, ClientClass, Hashed, CodeId, Deployment, Class, CodeHash, Chain,
} from './agent'
import { Error, Console, pluralize, bold, hideProperties } from './agent-base'
import { Client, fetchCodeHash, getSourceSpecifier } from './agent-client'
Expand Down Expand Up @@ -140,12 +139,13 @@ export class Uploader {
/** Upload an Uploadable (such as a Contract or Template).
* @returns Promise<Uploaded> */
async upload (contract: Uploadable & Partial<Uploaded>): Promise<Uploaded> {
type Mocknet = Chain & { uploads: Record<CodeId, { codeHash: CodeHash }> }
if (contract.codeId) {
this.log.log('found code id', contract.codeId)
if (this.reupload) {
this.log.log('reuploading because reupload is set')
} else if (this.agent?.chain?.isMocknet && contract.codeHash) {
const { codeHash } = (this.agent.chain as Mocknet.Chain).uploads[contract.codeId] || {}
const { codeHash } = (this.agent.chain as Mocknet).uploads[contract.codeId] || {}
if (codeHash === contract.codeHash) return contract as Uploaded
this.log.log('reuploading because mocknet is not stateful yet')
} else {
Expand All @@ -159,7 +159,7 @@ export class Uploader {
if (this.reupload) {
this.log.log('reuploading because reupload is set')
} else if (this.agent?.chain?.isMocknet) {
const { codeHash } = (this.agent.chain as Mocknet.Chain).uploads[cached.codeId] || {}
const { codeHash } = (this.agent.chain as Mocknet).uploads[cached.codeId] || {}
if (codeHash === contract.codeHash) return cached
this.log.log('reuploading because mocknet is not stateful yet')
} else {
Expand Down
9 changes: 0 additions & 9 deletions agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,3 @@ export * from './agent-token'
export * from './agent-client'
export * from './agent-deploy'
export * from './agent-services'
export * as Mocknet from './agent-mocknet'

// This is here to prevent a circular dependency:
import { Chain } from './agent-chain'
import * as Mocknet from './agent-mocknet'
Chain.mocknet = (options: Partial<Mocknet.Chain> = {}): Mocknet.Chain => new Mocknet.Chain({
id: 'mocknet',
...options
})
6 changes: 2 additions & 4 deletions agent/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fadroma/agent",
"version": "1.1.2",
"version": "2.0.0-rc.0",
"type": "module",
"main": "agent.ts",
"files": [ "*.ts", "**/*.ts" ],
Expand All @@ -19,9 +19,7 @@
"@hackbg/logs": "workspace:^2.0.2",
"@hackbg/many": "^1",
"@hackbg/oops": "workspace:^1.1",
"@hackbg/over": "^1.1",
"@noble/secp256k1": "^2.0.0",
"@noble/ed25519": "^2.0.0"
"@hackbg/over": "^1.1"
},
"devDependencies": {
"@hackbg/ensuite": "^1.1"
Expand Down
41 changes: 22 additions & 19 deletions connect/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
**/

import {
Console, Error, Chain, ChainMode, ChainId, Mocknet, bold, randomChainId
Console, Error, Chain, ChainMode, ChainId, bold, randomChainId
} from '@fadroma/agent'
import type { Agent, ChainRegistry } from '@fadroma/agent'
import * as Scrt from '@fadroma/scrt'
Expand All @@ -27,19 +27,11 @@ export * from '@fadroma/cw'
import { Config } from '@hackbg/conf'
import type { Environment } from '@hackbg/conf'

// Populate `Chain.variants` with catalog of possible connections:
Object.assign(Chain.variants as ChainRegistry, {
// Support for Secret Network
ScrtMainnet: Scrt.Chain.mainnet,
ScrtTestnet: Scrt.Chain.testnet,
// Devnet is injected here by @hackbg/fadroma
})

export * from '@hackbg/conf'

export * from '@fadroma/agent'

export { Scrt, Mocknet }
export { Scrt }

export default function connect <A extends Agent> (
config: Partial<ConnectConfig> = new ConnectConfig()
Expand All @@ -48,10 +40,21 @@ export default function connect <A extends Agent> (
}

export type ConnectMode =
|'Mocknet' // FIXME make chain-specific
|`Scrt${'Devnet'|'Testnet'|'Mainnet'}`
|`Scrt${'Mocknet'|'Devnet'|'Testnet'|'Mainnet'}`
|`OKP4${'Devnet'|'Testnet'}`

export const connectModes: Record<ConnectMode, (...args: any[])=>Chain> = {
// Support for Secret Network
ScrtMainnet: Scrt.mainnet,
ScrtTestnet: Scrt.testnet,
ScrtDevnet: () => { throw new Error('Devnets are only available via @hackbg/fadroma') },
ScrtMocknet: Scrt.Chain.mocknet,
// Support for OKP4
OKP4Testnet: CW.OKP4.testnet,
OKP4Devnet: () => { throw new Error('Devnets are only available via @hackbg/fadroma') },
// TODO: Support for custom chain
}

/** Connection configuration. Factory for `Chain` and `Agent` objects. */
export class ConnectConfig extends Config {
constructor (
Expand All @@ -68,10 +71,10 @@ export class ConnectConfig extends Config {

protected getChainId () {
const chainIds: Record<ConnectMode, ChainId> = {
Mocknet: 'mocknet',
ScrtDevnet: 'fadroma-devnet',
ScrtTestnet: this.scrt.testnetChainId,
ScrtMainnet: this.scrt.mainnetChainId,
ScrtMocknet: 'mocknet',
OKP4Devnet: 'fadroma-devnet-okp4',
OKP4Testnet: this.okp4.testnetChainId,
}
Expand All @@ -80,10 +83,10 @@ export class ConnectConfig extends Config {

protected getChainMode () {
const chainModes: Record<ConnectMode, ChainMode> = {
Mocknet: ChainMode.Mocknet,
ScrtDevnet: ChainMode.Devnet,
ScrtTestnet: ChainMode.Testnet,
ScrtMainnet: ChainMode.Mainnet,
ScrtMocknet: ChainMode.Mocknet,
OKP4Devnet: ChainMode.Devnet,
OKP4Testnet: ChainMode.Testnet,
}
Expand All @@ -102,7 +105,7 @@ export class ConnectConfig extends Config {
/** Name of stored mnemonic to use for authentication (currently devnet only) */
agentName: string = this.getString('FADROMA_AGENT', ()=>'Admin')
/** Name of chain to use. */
chain?: keyof ChainRegistry = this.getString('FADROMA_CHAIN', ()=>'Mocknet')
chain?: ConnectMode = this.getString('FADROMA_CHAIN', ()=>'ScrtMocknet')
/** Override chain id. */
chainId?: ChainId
/** Override chain mode. */
Expand All @@ -115,17 +118,17 @@ export class ConnectConfig extends Config {
= this.getString('FADROMA_MNEMONIC', ()=>undefined)
/** Create the Chain instance specified by the configuration. */
getChain <C extends Chain> (
chainToGet: keyof ChainRegistry|ChainRegistry[keyof ChainRegistry]|undefined = this.chain
chainToGet: ConnectMode|((...args: any[])=>Chain)|undefined = this.chain
): C {
if (!chainToGet) {
chainToGet = this.chain
if (!chainToGet) throw new Error.Missing.Chain()
}
if (typeof chainToGet === 'string') { // allow name to be passed
chainToGet = Chain.variants[chainToGet]
chainToGet = connectModes[chainToGet as ConnectMode]
}
if (!chainToGet) { // if still unspecified, throw
throw new ConnectError.UnknownChainSelected(this.chain!, Chain.variants)
throw new ConnectError.UnknownChainSelected(this.chain!, connectModes)
}
return chainToGet({ config: this }) as C // create Chain object
}
Expand All @@ -150,7 +153,7 @@ export class ConnectConfig extends Config {
export class ConnectConsole extends Console {
label = 'Fadroma Connect'

supportedChains (supportedChains: Record<string, unknown> = Chain.variants) {
supportedChains (supportedChains: Record<string, unknown> = connectModes) {
this.br()
this.info('Known chain names:')
for (const chain of Object.keys(supportedChains).sort()) {
Expand Down
4 changes: 4 additions & 0 deletions connect/cw/cw-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ class CWConsole extends Console {}

/** Generic CosmWasm-enabled chain. */
class CWChain extends Chain {

defaultDenom = ''

/** Query-only API handle. */
api?: CosmWasmClient

/** Async initialization. Populates the `api` property. */
get ready (): Promise<this & { api: CosmWasmClient }> {
const init = new Promise<this & { api: CosmWasmClient }>(async (resolve, reject)=>{
Expand All @@ -48,6 +51,7 @@ class CWChain extends Chain {
Object.defineProperty(this, 'ready', { get () { return init } })
return init
}

}

/** Generic agent for CosmWasm-enabled chains. */
Expand Down
46 changes: 25 additions & 21 deletions connect/cw/okp4/okp4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,26 @@ class OKP4Config extends Config {
static defaultTestnetUrl: string = 'https://okp4-testnet-rpc.polkachu.com/'
//'https://okp4-testnet-api.polkachu.com/'

constructor (
options: Partial<OKP4Config> = {},
environment?: Environment
) {
constructor (options: Partial<OKP4Config> = {}, environment?: Environment) {
super(environment)
this.override(options)
}

testnetChainId: string = this.getString(
'FADROMA_OKP4_TESTNET_CHAIN_ID',
() => OKP4Config.defaultTestnetChainId)
() => OKP4Config.defaultTestnetChainId
)

testnetUrl: string = this.getString(
'FADROMA_OKP4_TESTNET_URL',
() => OKP4Config.defaultTestnetUrl)
() => OKP4Config.defaultTestnetUrl
)

}

/** OKP4 chain. */
class OKP4Chain extends Chain {

/** Default denomination of gas token. */
static defaultDenom = 'uknow'

/** @returns Fee in uscrt */
static gas = (amount: Uint128|number) => new Fee(amount, this.defaultDenom)

/** Set permissive fees by default. */
static defaultFees: AgentFees = {
upload: this.gas(1000000),
init: this.gas(1000000),
exec: this.gas(1000000),
send: this.gas(1000000),
}

/** Default Agent class to use. */
declare Agent: AgentClass<OKP4Agent>

Expand All @@ -64,6 +50,7 @@ class OKP4Chain extends Chain {
constructor (options: Partial<OKP4Chain> & { config?: OKP4Config } = {
config: new OKP4Config()
}) {
console.log({options})
super(options)
}

Expand Down Expand Up @@ -105,6 +92,21 @@ class OKP4Chain extends Chain {
const ids = Object.values(lawStoneCodeIds)
return await getContractsById(this.id, api, LawStone, ids, map)
}

/** Default denomination of gas token. */
static defaultDenom = 'uknow'

/** @returns Fee in uscrt */
static gas = (amount: Uint128|number) => new Fee(amount, this.defaultDenom)

/** Set permissive fees by default. */
static defaultFees: AgentFees = {
upload: this.gas(1000000),
init: this.gas(1000000),
exec: this.gas(1000000),
send: this.gas(1000000),
}

}

async function getContractsById <C extends Client> (
Expand All @@ -128,7 +130,9 @@ async function getContractsById <C extends Client> (
const addresses = await api.getContracts(codeId)

for (const address of addresses) {
const contract = new $C({ address, codeHash, codeId: String(codeId), } as Partial<C>)
const contract = new $C(
{ address, codeHash, codeId: String(codeId) } as Partial<C>
)
contract.meta.chainId = chainId
if (map) {
(contracts as Map<Address, C>).set(address, contract)
Expand Down
2 changes: 1 addition & 1 deletion connect/cw/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"files": [ "*.ts" ],
"description": "CosmJS Stargate integration for Fadroma, incl. OKP4 support.",
"dependencies": {
"@fadroma/agent": "workspace:1.1.2",
"@fadroma/agent": "workspace:2.0.0-rc.0",
"@hackbg/conf": "workspace:3.1.5",
"@hackbg/cosmjs-esm": "workspace:1.0.0-rc.31",
"@noble/hashes": "^1.3.2",
Expand Down
4 changes: 2 additions & 2 deletions connect/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fadroma/connect",
"version": "3.4.15-rc.7",
"version": "4.0.0-rc.0",
"type": "module",
"main": "./connect.ts",
"files": [ "*.ts", "!cw", "!evm", "!scrt" ],
Expand All @@ -10,7 +10,7 @@
"ubik": "pnpm check && ubik"
},
"dependencies": {
"@fadroma/agent": "workspace:1.1.2",
"@fadroma/agent": "workspace:2.0.0-rc.0",
"@fadroma/scrt": "workspace:10.1.10-rc.13",
"@fadroma/cw": "workspace:0.6.0",
"@hackbg/conf": "workspace:3.1.5"
Expand Down
8 changes: 5 additions & 3 deletions connect/scrt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
"files": [ "*.ts" ],
"description": "Fadroma support for Secret Network. Provides a SecretJS-based implementation of the base classes in @fadroma/agent to operate smart contracts on the Secret Network.",
"dependencies": {
"@fadroma/agent": "workspace:1.1.2",
"@hackbg/conf": "workspace:3.1.5",
"@hackbg/secretjs-esm": "workspace:1.9.3-patch.26"
"@fadroma/agent": "workspace:2.0.0-rc.0",
"@hackbg/conf": "workspace:3.1.5",
"@hackbg/secretjs-esm": "workspace:1.9.3-patch.26",
"@noble/secp256k1": "^2.0.0",
"@noble/ed25519": "^2.0.0"
},
"devDependencies": {
"@hackbg/ensuite": "1.x"
Expand Down
Loading

0 comments on commit 85300fb

Please sign in to comment.