Skip to content

Commit

Permalink
wip 22
Browse files Browse the repository at this point in the history
  • Loading branch information
egasimus committed Oct 30, 2023
1 parent 5c9f77a commit 438b365
Show file tree
Hide file tree
Showing 35 changed files with 674 additions and 934 deletions.
371 changes: 59 additions & 312 deletions agent/_agentchain.ts.old

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions agent/base.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/** Fadroma. Copyright (C) 2023 Hack.bg. License: GNU AGPLv3 or custom.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. **/
import assert from 'node:assert'
import { Console, Error, assign, into, intoArray, intoRecord } from './base'

Expand Down
6 changes: 3 additions & 3 deletions agent/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ export type Name = string
/** A transaction message that can be sent to a contract. */
export type Message = string|Record<string, unknown>

/** A transaction hash, uniquely identifying an executed transaction on a chain. */
export type TxHash = string

/** An address on a chain. */
export type Address = string

/** A transaction hash, uniquely identifying an executed transaction on a chain. */
export type TxHash = string

/** Error kinds. */
class FadromaError extends BaseError {
/** Thrown when a required parameter is missing. */
Expand Down
3 changes: 3 additions & 0 deletions agent/batch.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/** Fadroma. Copyright (C) 2023 Hack.bg. License: GNU AGPLv3 or custom.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. **/
import assert from 'node:assert'
import type { Agent } from './agent'
import { Batch } from './batch'
Expand Down
3 changes: 3 additions & 0 deletions agent/chain.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/** Fadroma. Copyright (C) 2023 Hack.bg. License: GNU AGPLv3 or custom.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. **/
import assert from 'node:assert'
import { fixture } from '../fixtures/fixtures'

Expand Down
176 changes: 99 additions & 77 deletions agent/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. **/
import type { Name, Address, Class, Into, Many, TxHash, Label, Message } from './base'
import { Error, Console, bold, into } from './base'
import { Error, Console, bold, into, assign } from './base'
import type { ICoin, IFee } from './token'
import type { Batch, BatchClass, BatchCallback } from './batch'
import type { UploadStore } from './store'
Expand All @@ -22,9 +22,6 @@ export enum ChainMode {
/** The unique ID of a chain. */
export type ChainId = string

/** A collection of functions that return Chain instances. */
export type ChainRegistry = Record<string, (config: any)=>Chain>

/** Interface for Devnet (implementation is in @hackbg/fadroma). */
export interface DevnetHandle {
accounts: string[]
Expand Down Expand Up @@ -62,34 +59,34 @@ export abstract class Chain {
if (devnet) {
Object.defineProperties(this, {
id: {
enumerable: true,
configurable: true,
get: () => devnet.chainId,
set: () => { throw new Error("can't override chain id of devnet") }
enumerable: true, configurable: true,
get: () => devnet.chainId, set: () => {
throw new Error("can't override chain id of devnet")
}
},
url: {
enumerable: true,
configurable: true,
get: () => devnet.url.toString(),
set: () => { throw new Error("can't override url of devnet") }
enumerable: true, configurable: true,
get: () => devnet.url.toString(), set: () => {
throw new Error("can't override url of devnet")
}
},
'mode': {
enumerable: true,
configurable: true,
get: () => Chain.Mode.Devnet,
set: () => { throw new Error("chain.mode: can't override") }
enumerable: true, configurable: true,
get: () => Chain.Mode.Devnet, set: () => {
throw new Error("chain.mode: can't override")
}
},
'devnet': {
enumerable: true,
configurable: true,
get: () => devnet,
set: () => { throw new Error("chain.devnet: can't override") }
enumerable: true, configurable: true,
get: () => devnet, set: () => {
throw new Error("chain.devnet: can't override")
}
},
'stopped': {
enumerable: true,
configurable: true,
get: () => !this.devnet!.running,
set: () => { throw new Error("chain.stopped: can't override") }
enumerable: true, configurable: true,
get: () => !this.devnet!.running, set: () => {
throw new Error("chain.stopped: can't override")
}
}
})
if (id && id !== devnet.chainId) {
Expand All @@ -102,23 +99,25 @@ export abstract class Chain {
this.log.warn('chain.mode: ignoring override (devnet)')
}
} else {
if (id) {
Object.defineProperty(this, 'id', {
enumerable: true,
writable: false,
value: id
})
}
if (mode) {
Object.defineProperty(this, 'mode', {
enumerable: true,
writable: false,
value: mode
})
}
Object.defineProperties(this, {
id: {
enumerable: true, writable: false, value: id
},
mode: {
enumerable: true, writable: false, value: mode || Chain.Mode.Mocknet
}
})
this.url = url ?? this.url
}

if (this.mode === Chain.Mode.Mocknet) {
Object.defineProperty(this, 'url', {
enumerable: true,
writable: false,
value: `fadroma://mocknet-${this.id}`
})
}

Object.defineProperty(this, 'log', {
enumerable: false,
writable: true,
Expand Down Expand Up @@ -147,54 +146,76 @@ export abstract class Chain {
Agent: AgentClass<Agent> = (this.constructor as ChainClass<unknown>).Agent

/** Compact string tag for console representation. */
get [Symbol.toStringTag]() { return `${this.mode}: ${this.id} @ ${this.url}` }
get [Symbol.toStringTag]() {
return this.mode || '(unspecified mode)'
}

/** The unique chain id. */
get id (): ChainId { throw new Error("chain.id: not set") }
set id (id: string) { throw new Error("chain.id: can't override") }
get id (): ChainId {
throw new Error("chain.id: not set")
}
set id (id: string) {
throw new Error("chain.id: can't override")
}

/** Whether this is mainnet, public testnet, local devnet, or mocknet. */
get mode (): ChainMode { throw new Error('chain.mode: not set') }
get mode (): ChainMode {
throw new Error('chain.mode: not set')
}

/** Whether this is a mainnet. */
get isMainnet () { return this.mode === ChainMode.Mainnet }
get isMainnet () {
return this.mode === ChainMode.Mainnet
}

/** Whether this is a testnet. */
get isTestnet () { return this.mode === ChainMode.Testnet }
get isTestnet () {
return this.mode === ChainMode.Testnet
}

/** Whether this is a devnet. */
get isDevnet () { return this.mode === ChainMode.Devnet }
get isDevnet () {
return this.mode === ChainMode.Devnet
}

/** Whether this is a mocknet. */
get isMocknet () { return this.mode === ChainMode.Mocknet }
get isMocknet () {
return this.mode === ChainMode.Mocknet
}

/** Whether this is a devnet or mocknet. */
get devMode () { return this.isDevnet || this.isMocknet }
get devMode () {
return this.isDevnet || this.isMocknet
}

/** Return self. */
get chain () { return this }

api?: unknown
get chain () {
return this
}

abstract getApi (): unknown
/** One-time asynchronous initialization
* (async stuff that would go in the constructor
* if it was possible for constructors to be async.) */
protected abstract init (): Promise<this>

get ready () {
get ready (): Promise<this> {
if (this.isDevnet && !this.devnet) {
throw new Error("the chain is marked as a devnet but is missing the devnet handle")
}
type This = this
type ThisWithApi = This & { api: NonNullable<This["api"]> }
const init = new Promise<ThisWithApi>(async (resolve, reject)=>{
const init = new Promise<this>(async (resolve, reject)=>{
if (this.isDevnet) {
await this.devnet!.start()
}
if (!this.api) {
if (!this.url) throw new Error("the chain's url property is not set")
this.api = await Promise.resolve(this.getApi())
if (!this.url && !this.isMocknet) {
throw new Error("the chain's url property is not set")
}
return resolve(this.init())
})
Object.defineProperty(this, 'ready', {
get () {
return init
}
return resolve(this as ThisWithApi)
})
Object.defineProperty(this, 'ready', { get () { return init } })
return init
}

Expand Down Expand Up @@ -305,44 +326,45 @@ export abstract class Agent {
/** Logger. */
log = new Console(this.constructor.name)
/** The friendly name of the agent. */
name?: string
name?: string
/** The chain on which this agent operates. */
chain?: Chain
chain?: Chain
/** The address from which transactions are signed and sent. */
address?: Address
address?: Address
/** Default fee maximums for send, upload, init, and execute. */
fees?: AgentFees
fees?: AgentFees
/** The Batch subclass to use. */
Batch: BatchClass<Batch> = (this.constructor as AgentClass<typeof this>).Batch
Batch: BatchClass<Batch> = (this.constructor as AgentClass<typeof this>).Batch
/** The default Batch class used by this Agent. */
static Batch: BatchClass<Batch> // populated below

constructor (options: Partial<Agent> = {}) {
this.chain = options.chain ?? this.chain
this.name = options.name ?? this.name
this.fees = options.fees ?? this.fees
this.address = options.address ?? this.address
Object.defineProperties(this, {
chain: { enumerable: false, writable: true, configurable: true },
address: { enumerable: false, writable: true, configurable: true },
log: { enumerable: false, writable: true, configurable: true },
Batch: { enumerable: false, writable: true, configurable: true },
assign(this, options, ['name', 'chain', 'address', 'fees'])
Object.defineProperty(this, 'log', {
enumerable: false, configurable: true, writable: true,
})
}

get [Symbol.toStringTag]() {
return `${this.address} @ ${this.chain?.id}`
return `${this.name||this.address} @ ${this.chain?.id}`
}

/** One-time asynchronous initialization
* (async stuff that would go in the constructor
* if it was possible for constructors to be async.) */
protected abstract init (): Promise<this>

/** Complete the asynchronous initialization of this Agent. */
get ready (): Promise<this> {
const init = new Promise<this>(async (resolve, reject)=>{
try {
if (this.chain?.devnet) await this.chain?.devnet.start()
if (this.chain?.devnet) {
await this.chain?.devnet.start()
}
if (!this.mnemonic && this.name && this.chain?.devnet) {
Object.assign(this, await this.chain?.devnet.getAccount(this.name))
}
resolve(this)
resolve(this.init())
} catch (e) {
reject(e)
}
Expand Down
3 changes: 3 additions & 0 deletions agent/client.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/** Fadroma. Copyright (C) 2023 Hack.bg. License: GNU AGPLv3 or custom.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. **/
import assert from 'node:assert'
import { Chain } from './chain'
import { StubChain, StubAgent } from './stub'
Expand Down
3 changes: 3 additions & 0 deletions agent/client.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/** Fadroma. Copyright (C) 2023 Hack.bg. License: GNU AGPLv3 or custom.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. **/
import { Console, Error } from './base'
import type { Class, Address, Message } from './base'
import type { Agent, Chain } from './chain'
Expand Down
3 changes: 3 additions & 0 deletions agent/code.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/** Fadroma. Copyright (C) 2023 Hack.bg. License: GNU AGPLv3 or custom.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. **/
import assert from 'node:assert'
import { ContractCode, SourceCode, CompiledCode, UploadedCode } from './code'
import { StubAgent, StubBuilder } from './stub'
Expand Down
3 changes: 3 additions & 0 deletions agent/code.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/** Fadroma. Copyright (C) 2023 Hack.bg. License: GNU AGPLv3 or custom.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. **/
import { Console, assign } from './base'
import type { Class, Address, TxHash } from './base'
import type { ChainId, Agent } from './chain'
Expand Down
3 changes: 3 additions & 0 deletions agent/deploy.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/** Fadroma. Copyright (C) 2023 Hack.bg. License: GNU AGPLv3 or custom.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. **/
import assert from 'node:assert'
import { Console } from './base'
import { Deployment, DeploymentContractLabel } from './deploy'
Expand Down
3 changes: 3 additions & 0 deletions agent/store.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/** Fadroma. Copyright (C) 2023 Hack.bg. License: GNU AGPLv3 or custom.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. **/
import assert from 'node:assert'
import { UploadStore, DeployStore } from './store'
import { UploadedCode } from './code'
Expand Down
3 changes: 3 additions & 0 deletions agent/token.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/** Fadroma. Copyright (C) 2023 Hack.bg. License: GNU AGPLv3 or custom.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. **/
import assert from 'node:assert'
import {
addZeros,
Expand Down
2 changes: 1 addition & 1 deletion 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, bold } from '@fadroma/agent'
import type { Agent, ChainRegistry } from '@fadroma/agent'
import type { Agent } from '@fadroma/agent'
import * as Scrt from '@fadroma/scrt'
import * as CW from '@fadroma/cw'

Expand Down
Loading

0 comments on commit 438b365

Please sign in to comment.