@helios-lang/contract-utils 0.3.5 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/package.json +1 -1
  2. package/src/artifacts/Artifact.js +14 -0
  3. package/src/artifacts/ArtifactWriter.js +199 -0
  4. package/src/artifacts/ChildArtifactWriter.js +118 -0
  5. package/src/artifacts/FunctionArtifact.js +90 -0
  6. package/src/artifacts/ModuleArtifact.js +83 -0
  7. package/src/artifacts/RootArtifact.js +105 -0
  8. package/src/artifacts/TypeArtifact.js +104 -0
  9. package/src/artifacts/ValidatorArtifact.js +158 -0
  10. package/src/artifacts/index.js +1 -0
  11. package/src/artifacts/symbols.js +16 -0
  12. package/src/cast/Cast.js +45 -9
  13. package/src/cast/UserFunc.js +182 -131
  14. package/src/cast/index.js +12 -3
  15. package/src/codegen/LoadedScriptsWriter.js +35 -11
  16. package/src/codegen/TypeSchema.js +123 -0
  17. package/src/context/index.js +1 -0
  18. package/src/hl2ts.js +0 -4
  19. package/src/index.js +36 -8
  20. package/src/internal.js +12 -0
  21. package/types/artifacts/Artifact.d.ts +11 -0
  22. package/types/artifacts/Artifact.d.ts.map +1 -0
  23. package/types/artifacts/ArtifactWriter.d.ts +64 -0
  24. package/types/artifacts/ArtifactWriter.d.ts.map +1 -0
  25. package/types/artifacts/ChildArtifactWriter.d.ts +35 -0
  26. package/types/artifacts/ChildArtifactWriter.d.ts.map +1 -0
  27. package/types/artifacts/FunctionArtifact.d.ts +14 -0
  28. package/types/artifacts/FunctionArtifact.d.ts.map +1 -0
  29. package/types/artifacts/ModuleArtifact.d.ts +29 -0
  30. package/types/artifacts/ModuleArtifact.d.ts.map +1 -0
  31. package/types/artifacts/RootArtifact.d.ts +11 -0
  32. package/types/artifacts/RootArtifact.d.ts.map +1 -0
  33. package/types/artifacts/TypeArtifact.d.ts +17 -0
  34. package/types/artifacts/TypeArtifact.d.ts.map +1 -0
  35. package/types/artifacts/ValidatorArtifact.d.ts +17 -0
  36. package/types/artifacts/ValidatorArtifact.d.ts.map +1 -0
  37. package/types/artifacts/index.d.ts +2 -0
  38. package/types/artifacts/index.d.ts.map +1 -0
  39. package/types/artifacts/symbols.d.ts +8 -0
  40. package/types/artifacts/symbols.d.ts.map +1 -0
  41. package/types/cast/Cast.d.ts +31 -0
  42. package/types/cast/Cast.d.ts.map +1 -1
  43. package/types/cast/UserFunc.d.ts +39 -0
  44. package/types/cast/UserFunc.d.ts.map +1 -1
  45. package/types/cast/index.d.ts +2 -2
  46. package/types/codegen/LoadedScriptsWriter.d.ts +18 -0
  47. package/types/codegen/LoadedScriptsWriter.d.ts.map +1 -1
  48. package/types/codegen/TypeSchema.d.ts +5 -0
  49. package/types/codegen/TypeSchema.d.ts.map +1 -1
  50. package/types/context/writeContractContextArtifacts.d.ts +30 -0
  51. package/types/context/writeContractContextArtifacts.d.ts.map +1 -0
  52. package/types/hl2ts.d.ts.map +1 -1
  53. package/types/index.d.ts +30 -4
  54. package/types/index.d.ts.map +1 -1
  55. package/types/internal.d.ts +5 -0
  56. package/types/internal.d.ts.map +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helios-lang/contract-utils",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "description": "Convenience and type-safety utilities for using Helios validators from within Typescript",
5
5
  "main": "src/index.js",
6
6
  "types": "types/index.d.ts",
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @import { FileSystem } from "../index.js"
3
+ */
4
+
5
+ /**
6
+ * @typedef {object} Artifact
7
+ * @prop {string} dir
8
+ * @prop {FileSystem} fs
9
+ * @prop {boolean} isMainnet
10
+ * @prop {(line: string) => void} writeDeclLine
11
+ * @prop {(line: string) => void} writeDefLine
12
+ * @prop {(name: string) => void} writeAggregateExport
13
+ * @prop {() => void} save
14
+ */
@@ -0,0 +1,199 @@
1
+ import { makeStringWriter } from "@helios-lang/codec-utils"
2
+ import { expectDefined } from "@helios-lang/type-utils"
3
+
4
+ /**
5
+ * @import { StringWriter } from "@helios-lang/codec-utils"
6
+ * @import { FileSystem } from "../index.js"
7
+ */
8
+
9
+ export class ArtifactWriter {
10
+ /**
11
+ * @readonly
12
+ * @type {FileSystem}
13
+ */
14
+ fs
15
+
16
+ /**
17
+ * @readonly
18
+ * @type {string}
19
+ */
20
+ dir
21
+
22
+ /**
23
+ * @private
24
+ * @type {StringWriter}
25
+ */
26
+ decl
27
+
28
+ /**
29
+ * @private
30
+ * @type {StringWriter}
31
+ */
32
+ def
33
+
34
+ /**
35
+ * @private
36
+ * @type {[string, string, boolean][]}
37
+ */
38
+ imports
39
+
40
+ /**
41
+ * @param {FileSystem} fs
42
+ * @param {string} dir
43
+ */
44
+ constructor(fs, dir) {
45
+ this.fs = fs
46
+ this.dir = dir
47
+
48
+ this.decl = makeStringWriter()
49
+ this.def = makeStringWriter()
50
+ this.imports = []
51
+ }
52
+
53
+ /**
54
+ * @param {string} name
55
+ * @param {string} from
56
+ * @param {boolean} [isType]
57
+ * @returns {ArtifactWriter}
58
+ */
59
+ addImport(name, from, isType = false) {
60
+ this.imports.push([name, from, isType])
61
+ return this
62
+ }
63
+
64
+ /**
65
+ * @param {string} line
66
+ * @returns {ArtifactWriter}
67
+ */
68
+ writeDeclLine(line) {
69
+ this.decl.writeLine(line)
70
+ return this
71
+ }
72
+
73
+ /**
74
+ * @param {string} line
75
+ * @returns {ArtifactWriter}
76
+ */
77
+ writeDefLine(line) {
78
+ this.def.writeLine(line)
79
+ return this
80
+ }
81
+
82
+ /**
83
+ * @param {string} name
84
+ * @returns {ArtifactWriter}
85
+ */
86
+ writeAggregateExport(name) {
87
+ return this.writeDeclLine(
88
+ `export * as ${name} from "./${name}/index.js"`
89
+ ).writeDefLine(`export * as ${name} from "./${name}/index.js"`)
90
+ }
91
+
92
+ /**
93
+ * Write the .d.ts and .js files to the FS
94
+ */
95
+ save() {
96
+ this.fs.mkdirSync(this.dir, { recursive: true })
97
+
98
+ let declString = this.decl.finalize()
99
+ let defString = this.def.finalize()
100
+
101
+ if (this.imports.length > 0) {
102
+ const imps = groupImports(this.imports)
103
+
104
+ const declImp = makeStringWriter()
105
+ const defImp = makeStringWriter()
106
+
107
+ for (let imp of imps) {
108
+ const { from, typeSymbols, defSymbols } = imp
109
+
110
+ if (typeSymbols.length == 1) {
111
+ declImp.writeLine(
112
+ `import type { ${typeSymbols[0]} } from "${from}"`
113
+ )
114
+ } else if (typeSymbols.length > 1) {
115
+ declImp.writeLine(`import type {`)
116
+
117
+ typeSymbols.forEach((s, i) => {
118
+ declImp.writeLine(
119
+ ` ${s}${i < typeSymbols.length - 1 ? "," : ""}`
120
+ )
121
+ })
122
+
123
+ declImp.writeLine(`} from "${from}"`)
124
+ }
125
+
126
+ if (defSymbols.length == 1) {
127
+ defImp.writeLine(
128
+ `import { ${defSymbols[0]} } from "${from}"`
129
+ )
130
+ } else if (defSymbols.length > 1) {
131
+ defImp.writeLine(`import {`)
132
+
133
+ defSymbols.forEach((s, i) => {
134
+ defImp.writeLine(
135
+ ` ${s}${i < defSymbols.length - 1 ? "," : ""}`
136
+ )
137
+ })
138
+
139
+ defImp.writeLine(`} from "${from}"`)
140
+ }
141
+ }
142
+
143
+ const declImports = declImp.finalize()
144
+ const defImports = defImp.finalize()
145
+
146
+ if (declImports.length > 0) {
147
+ declString = `${declImports}\n${declString}`
148
+ }
149
+
150
+ if (defImports.length > 0) {
151
+ defString = `${defImports}\n${defString}`
152
+ }
153
+ }
154
+
155
+ this.fs.writeFileSync(`${this.dir}/index.d.ts`, declString)
156
+ this.fs.writeFileSync(`${this.dir}/index.js`, defString)
157
+ }
158
+ }
159
+
160
+ /**
161
+ * @param {[string, string, boolean][]} imports
162
+ * @returns {{from: string, typeSymbols: string[], defSymbols: string[]}[]}
163
+ */
164
+ function groupImports(imports) {
165
+ /**
166
+ * @type {Map<string, {name: string, isType: boolean}[]>}
167
+ */
168
+ const m = new Map()
169
+
170
+ for (let imp of imports) {
171
+ const [name, from, isType] = imp
172
+
173
+ const prev = m.get(from)
174
+
175
+ if (prev) {
176
+ prev.push({ name, isType })
177
+ } else {
178
+ m.set(from, [{ name, isType }])
179
+ }
180
+ }
181
+
182
+ const keys = Array.from(m.keys()).sort()
183
+
184
+ return keys.map((key) => {
185
+ const symbols = expectDefined(m.get(key))
186
+
187
+ return {
188
+ from: key,
189
+ typeSymbols: symbols
190
+ .filter((symbol) => symbol.isType)
191
+ .sort((a, b) => a.name.localeCompare(b.name))
192
+ .map((symbol) => symbol.name),
193
+ defSymbols: symbols
194
+ .filter((symbol) => !symbol.isType)
195
+ .sort((a, b) => a.name.localeCompare(b.name))
196
+ .map((symbol) => symbol.name)
197
+ }
198
+ })
199
+ }
@@ -0,0 +1,118 @@
1
+ import { bytesToHex } from "@helios-lang/codec-utils"
2
+ import { makeUplcSourceMap } from "@helios-lang/uplc"
3
+ import { ArtifactWriter } from "./ArtifactWriter.js"
4
+
5
+ /**
6
+ * @import { UplcProgram } from "@helios-lang/uplc"
7
+ * @import { Artifact } from "./Artifact.js"
8
+ */
9
+
10
+ export class ChildArtifactWriter extends ArtifactWriter {
11
+ /**
12
+ * @readonly
13
+ * @type {Artifact}
14
+ */
15
+ parent
16
+
17
+ /**
18
+ * @readonly
19
+ * @type {string}
20
+ */
21
+ name
22
+
23
+ /**
24
+ * @param {Artifact} parent
25
+ * @param {string} name
26
+ */
27
+ constructor(parent, name) {
28
+ super(parent.fs, `${parent.dir}/${name}`)
29
+
30
+ this.parent = parent
31
+ this.name = name
32
+ }
33
+
34
+ /**
35
+ * @type {boolean}
36
+ */
37
+ get isMainnet() {
38
+ return this.parent.isMainnet
39
+ }
40
+
41
+ /**
42
+ * @param {string} name
43
+ * @param {UplcProgram} program
44
+ * @returns {ChildArtifactWriter}
45
+ */
46
+ writeProgram(name, program) {
47
+ if (program.plutusVersion == "PlutusScriptV1") {
48
+ this.addImport("UplcProgramV1", "@helios-lang/uplc", true)
49
+ this.addImport("decodeUplcProgramV1FromCbor", "@helios-lang/uplc")
50
+
51
+ this.writeDeclLine(
52
+ `export const ${name}: UplcProgramV1`
53
+ ).writeDefLine(
54
+ `export const ${name} = ${stringifyProgram("decodeUplcProgramV1FromCbor", program)}`
55
+ )
56
+ } else if (program.plutusVersion == "PlutusScriptV2") {
57
+ this.addImport("UplcProgramV2", "@helios-lang/uplc", true)
58
+ this.addImport("decodeUplcProgramV2FromCbor", "@helios-lang/uplc")
59
+
60
+ this.writeDeclLine(
61
+ `export const ${name}: UplcProgramV2`
62
+ ).writeDefLine(
63
+ `export const ${name} = ${stringifyProgram("decodeUplcProgramV2FromCbor", program)}`
64
+ )
65
+ } else if (program.plutusVersion == "PlutusScriptV3") {
66
+ this.addImport("UplcProgramV3", "@helios-lang/uplc", true)
67
+ this.addImport("decodeUplcProgramV3FromCbor", "@helios-lang/uplc")
68
+
69
+ this.writeDeclLine(
70
+ `export const ${name}: UplcProgramV3`
71
+ ).writeDefLine(
72
+ `export const ${name} = ${stringifyProgram("decodeUplcProgramV3FromCbor", program)}`
73
+ )
74
+ } else {
75
+ throw new Error("unhandled Plutus version")
76
+ }
77
+
78
+ return this
79
+ }
80
+ }
81
+
82
+ /**
83
+ *
84
+ * @param {string} decoderName
85
+ * @param {UplcProgram} program
86
+ * @returns {string}
87
+ */
88
+ function stringifyProgram(decoderName, program) {
89
+ const sourceMap = makeUplcSourceMap({ term: program.root })
90
+
91
+ return `${decoderName}(
92
+ "${bytesToHex(program.toCbor())}",
93
+ {${stringifyAlt("decodeUplcProgramV2FromCbor", program.alt)}
94
+ sourceMap: ${JSON.stringify(sourceMap.toJsonSafe(), undefined, 4).split("\n").join("\n ")}
95
+ }
96
+ )`
97
+ }
98
+
99
+ /**
100
+ * @param {string} decoderName
101
+ * @param {UplcProgram | undefined} alt
102
+ * @returns {string}
103
+ */
104
+ function stringifyAlt(decoderName, alt) {
105
+ if (!alt) {
106
+ return ""
107
+ }
108
+
109
+ const sourceMap = makeUplcSourceMap({ term: alt.root })
110
+
111
+ return `
112
+ alt: ${decoderName}(
113
+ "${bytesToHex(alt.toCbor())}",
114
+ {
115
+ sourceMap: ${JSON.stringify(sourceMap.toJsonSafe(), undefined, 4).split("\n").join("\n ")}
116
+ }
117
+ ),`
118
+ }
@@ -0,0 +1,90 @@
1
+ import {
2
+ genFuncType,
3
+ genUserFuncArgsType,
4
+ genUserFuncRetType
5
+ } from "../codegen/LoadedScriptsWriter.js"
6
+ import { ChildArtifactWriter } from "./ChildArtifactWriter.js"
7
+
8
+ /**
9
+ * @import { UserFuncProps } from "../index.js"
10
+ * @import { Artifact } from "./Artifact.js"
11
+ * @import { FunctionDetails } from "./symbols.js"
12
+ */
13
+
14
+ /**
15
+ * @param {Artifact} parent
16
+ * @param {string} name
17
+ * @param {FunctionDetails} details
18
+ */
19
+ export function writeFunctionArtifact(parent, name, details) {
20
+ const artifact = new FunctionArtifact(parent, name)
21
+
22
+ const program = details.uplc
23
+ const props = details.props
24
+
25
+ artifact.writeProgram("$program", program)
26
+ artifact.writeProps(props)
27
+ artifact.writeEvals(props)
28
+
29
+ artifact.save()
30
+
31
+ parent.writeAggregateExport(name)
32
+ }
33
+
34
+ /**
35
+ * @implements {Artifact}
36
+ */
37
+ class FunctionArtifact extends ChildArtifactWriter {
38
+ /**
39
+ * @param {UserFuncProps} props
40
+ */
41
+ writeProps(props) {
42
+ this.addImport("UserFuncProps", "@helios-lang/contract-utils", true)
43
+
44
+ this.writeDeclLine(`export const $props: UserFuncProps`)
45
+ .writeDefLine(`/**
46
+ * @type {import("@helios-lang/contract-utils").UserFuncProps}
47
+ */
48
+ export const $props = ${JSON.stringify(props, undefined, 4)}`)
49
+ }
50
+
51
+ /**
52
+ * @param {UserFuncProps} props
53
+ */
54
+ writeEvals(props) {
55
+ const safeArgsType = genUserFuncArgsType(props)
56
+ const unsafeArgsType = genUserFuncArgsType(props, true)
57
+ const retType = genUserFuncRetType(props)
58
+ const unsafeRetType = genUserFuncRetType(props, true)
59
+
60
+ this.addImport("UplcLogger", "@helios-lang/uplc", true)
61
+ this.addImport("UplcData", "@helios-lang/uplc", true)
62
+ this.addImport("CekResult", "@helios-lang/uplc", true)
63
+
64
+ this.addImport("evalUserFunc", "@helios-lang/contract-utils")
65
+ .writeDeclLine(
66
+ `export function $eval(args${safeArgsType == "{}" ? "?" : ""}: ${safeArgsType}, logOptions?: UplcLogger | undefined): ${retType}`
67
+ )
68
+ .writeDefLine(
69
+ `export function $eval(args${safeArgsType == "{}" ? " = {}" : ""}, logOptions = undefined) {
70
+ return evalUserFunc($program, $props, args, logOptions)
71
+ }`
72
+ )
73
+ .addImport("evalUserFuncUnsafe", "@helios-lang/contract-utils")
74
+ .writeDeclLine(
75
+ `export function $evalUnsafe(args${unsafeArgsType == "{}" ? "?" : ""}: ${unsafeArgsType}, logOptions?: UplcLogger | undefined): ${unsafeRetType}`
76
+ )
77
+ .writeDefLine(
78
+ `export function $evalUnsafe(args${unsafeArgsType == "{}" ? " = {}" : ""}, logOptions = undefined) {
79
+ return evalUserFuncUnsafe($program, $props, args, logOptions)
80
+ }`
81
+ )
82
+ .addImport("profileUserFunc", "@helios-lang/contract-utils")
83
+ .writeDeclLine(
84
+ `export function $profile(args${unsafeArgsType == "{}" ? "?" : ""}: ${unsafeArgsType}, logOptions?: UplcLogger | undefined): CekResult`
85
+ )
86
+ .writeDefLine(`export function $profile(args${unsafeArgsType == "{}" ? " = {}" : ""}, logOptions = undefined) {
87
+ return profileUserFunc($program, $props, args, logOptions)
88
+ }`)
89
+ }
90
+ }
@@ -0,0 +1,83 @@
1
+ import { ArtifactWriter } from "./ArtifactWriter.js"
2
+ import { ChildArtifactWriter } from "./ChildArtifactWriter.js"
3
+ import { writeFunctionArtifact } from "./FunctionArtifact.js"
4
+ import { writeTypeArtifact } from "./TypeArtifact.js"
5
+
6
+ /**
7
+ * @import { FunctionDetails, ModuleSymbols, TypeDetails } from "./symbols.js"
8
+ */
9
+
10
+ /**
11
+ * Re-export Artifact to avoid issues with typescript private symbol errors
12
+ * @typedef {import("./Artifact.js").Artifact} Artifact
13
+ */
14
+
15
+ /**
16
+ * @param {Artifact} parent
17
+ * @param {string} name
18
+ * @param {ModuleSymbols} symbols
19
+ */
20
+ export function writeModuleArtifact(parent, name, symbols) {
21
+ const artifact = new ModuleArtifact(parent, name)
22
+
23
+ artifact.writeSymbols(symbols)
24
+
25
+ artifact.save()
26
+
27
+ parent.writeAggregateExport(name)
28
+ }
29
+
30
+ /**
31
+ * @implements {Artifact}
32
+ */
33
+ export class ModuleArtifact extends ChildArtifactWriter {
34
+ /**
35
+ * @param {Artifact} parent
36
+ * @param {string} name
37
+ */
38
+ constructor(parent, name) {
39
+ super(parent, name)
40
+ }
41
+
42
+ /**
43
+ * @param {ModuleSymbols} symbols
44
+ */
45
+ writeSymbols(symbols) {
46
+ for (let symbolName in symbols) {
47
+ if (symbolName.startsWith("$") || symbolName.includes("::")) {
48
+ continue
49
+ }
50
+
51
+ // either function or type
52
+ const symbolDetails = symbols[symbolName]
53
+
54
+ console.log(symbolName)
55
+ if ("schema" in symbolDetails) {
56
+ // collect members
57
+ const members = /** @type {Record<string, FunctionDetails>} */ (
58
+ Object.fromEntries(
59
+ Object.entries(symbols)
60
+ .filter(([key, value]) => {
61
+ return (
62
+ key.startsWith(`${symbolName}::`) &&
63
+ value["kind"] != "Cast"
64
+ )
65
+ })
66
+ .map(([key, value]) => [
67
+ key.slice(`${symbolName}::`.length),
68
+ value
69
+ ])
70
+ )
71
+ )
72
+
73
+ writeTypeArtifact(this, symbolName, symbolDetails, members)
74
+ } else {
75
+ writeFunctionArtifact(
76
+ this,
77
+ symbolName,
78
+ /** @type {FunctionDetails} */ (symbolDetails)
79
+ )
80
+ }
81
+ }
82
+ }
83
+ }
@@ -0,0 +1,105 @@
1
+ import { ArtifactWriter } from "./ArtifactWriter.js"
2
+ import { writeModuleArtifact } from "./ModuleArtifact.js"
3
+ import { writeValidatorArtifact } from "./ValidatorArtifact.js"
4
+
5
+ /**
6
+ * @import { ContractContext, ContractModuleContexts, ContractValidatorContexts, FileSystem, LoadedValidator, WriteContractContextArtifactsOptions } from "../index.js"
7
+ * @import { Artifact } from "./Artifact.js"
8
+ */
9
+
10
+ /**
11
+ * @param {any} context - TODO: make this typesafe (`ContractContext<any, any>` or `ContractContext` doesn't seem to work)
12
+ * @param {WriteContractContextArtifactsOptions} options - not optional, at least the fs and outDir must be specified
13
+ */
14
+ export function writeContractContextArtifacts(context, options) {
15
+ const isMainnet = extractIsMainnet(context)
16
+
17
+ const root = new RootArtifact(options.fs, options.outDir, isMainnet)
18
+
19
+ for (let moduleName in context) {
20
+ if (moduleName.startsWith("$")) {
21
+ continue
22
+ }
23
+
24
+ const moduleDetails = context[moduleName]
25
+
26
+ if (moduleDetails.$hash) {
27
+ writeValidatorArtifact(
28
+ root,
29
+ moduleName,
30
+ moduleDetails.$hash,
31
+ moduleDetails
32
+ )
33
+ } else {
34
+ writeModuleArtifact(root, moduleName, moduleDetails)
35
+ }
36
+ }
37
+
38
+ root.save()
39
+ }
40
+
41
+ /**
42
+ * @implements {Artifact}
43
+ */
44
+ class RootArtifact extends ArtifactWriter {
45
+ /**
46
+ * @readonly
47
+ * @type {boolean}
48
+ */
49
+ isMainnet
50
+
51
+ /**
52
+ * @param {FileSystem} fs
53
+ * @param {string} dir
54
+ * @param {boolean} isMainnet
55
+ */
56
+ constructor(fs, dir, isMainnet) {
57
+ super(fs, dir)
58
+
59
+ this.isMainnet = isMainnet
60
+ }
61
+ }
62
+
63
+ /**
64
+ * @param {any} context
65
+ * @returns {boolean}
66
+ */
67
+ function extractIsMainnet(context) {
68
+ /**
69
+ * @type {boolean | undefined}
70
+ */
71
+ let isMainnet = undefined
72
+
73
+ /**
74
+ * @param {boolean} b
75
+ */
76
+ const setIsMainnet = (b) => {
77
+ if (isMainnet === undefined) {
78
+ isMainnet = b
79
+ } else if (isMainnet != b) {
80
+ throw new Error("isMainnet inconsistent in contract context")
81
+ }
82
+ }
83
+
84
+ let stack = [context]
85
+
86
+ let obj = stack.pop()
87
+
88
+ while (obj) {
89
+ if ("isMainnet" in obj && typeof obj.isMainnet == "boolean") {
90
+ setIsMainnet(obj.isMainnet)
91
+ } else if ("$isMainnet" in obj && typeof obj.$isMainnet == "boolean") {
92
+ setIsMainnet(obj.$isMainnet)
93
+ }
94
+
95
+ for (let key in obj) {
96
+ if (typeof obj[key] === "object" && obj[key] !== null) {
97
+ stack.push(obj[key])
98
+ }
99
+ }
100
+
101
+ obj = stack.pop()
102
+ }
103
+
104
+ return isMainnet ?? false
105
+ }