Skip to content

Commit

Permalink
feat: export SorobanRpc.ContractClient
Browse files Browse the repository at this point in the history
This allows us to import it the usual way, instead of needing to do
things like

    import { ContractClient } from "stellar-sdk/lib/contract_client"

which doesn't work in the browser (because `lib`)
  • Loading branch information
chadoh committed May 10, 2024
1 parent 80b6fb5 commit 2ee6126
Show file tree
Hide file tree
Showing 15 changed files with 143 additions and 114 deletions.
93 changes: 44 additions & 49 deletions src/contract_spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { JSONSchema7, JSONSchema7Definition } from "json-schema";
import type { JSONSchema7, JSONSchema7Definition } from "json-schema";
import {
ScIntType,
XdrLargeInt,
xdr,
Address,
Contract,
scValToBigInt,
} from ".";
import { Ok } from "./rust_types";
} from "@stellar/stellar-base"
import { Ok } from "./soroban/contract_client/rust_result"

export interface Union<T> {
tag: string;
Expand Down Expand Up @@ -65,7 +65,7 @@ export class ContractSpec {
let entry = entries[0];
if (typeof entry === "string") {
this.entries = (entries as string[]).map((s) =>
xdr.ScSpecEntry.fromXDR(s, "base64")
xdr.ScSpecEntry.fromXDR(s, "base64"),
);
} else {
this.entries = entries as xdr.ScSpecEntry[];
Expand All @@ -83,7 +83,7 @@ export class ContractSpec {
.filter(
(entry) =>
entry.switch().value ===
xdr.ScSpecEntryKind.scSpecEntryFunctionV0().value
xdr.ScSpecEntryKind.scSpecEntryFunctionV0().value,
)
.map((entry) => entry.functionV0());
}
Expand Down Expand Up @@ -164,9 +164,7 @@ export class ContractSpec {
}
let output = outputs[0];
if (output.switch().value === xdr.ScSpecType.scSpecTypeResult().value) {
return new Ok(
this.scValToNative(val, output.result().okType())
);
return new Ok(this.scValToNative(val, output.result().okType()));
}
return this.scValToNative(val, output);
}
Expand All @@ -181,7 +179,7 @@ export class ContractSpec {
*/
findEntry(name: string): xdr.ScSpecEntry {
let entry = this.entries.find(
(entry) => entry.value().name().toString() === name
(entry) => entry.value().name().toString() === name,
);
if (!entry) {
throw new Error(`no such entry: ${name}`);
Expand Down Expand Up @@ -220,7 +218,7 @@ export class ContractSpec {
return xdr.ScVal.scvVoid();
default:
throw new TypeError(
`Type ${ty} was not void, but value was null`
`Type ${ty} was not void, but value was null`,
);
}
}
Expand All @@ -232,7 +230,7 @@ export class ContractSpec {
if (val instanceof Address) {
if (ty.switch().value !== xdr.ScSpecType.scSpecTypeAddress().value) {
throw new TypeError(
`Type ${ty} was not address, but value was Address`
`Type ${ty} was not address, but value was Address`,
);
}
return val.toScVal();
Expand All @@ -241,7 +239,7 @@ export class ContractSpec {
if (val instanceof Contract) {
if (ty.switch().value !== xdr.ScSpecType.scSpecTypeAddress().value) {
throw new TypeError(
`Type ${ty} was not address, but value was Address`
`Type ${ty} was not address, but value was Address`,
);
}
return val.address().toScVal();
Expand All @@ -254,7 +252,7 @@ export class ContractSpec {
let bytes_n = ty.bytesN();
if (copy.length !== bytes_n.n()) {
throw new TypeError(
`expected ${bytes_n.n()} bytes, but got ${copy.length}`
`expected ${bytes_n.n()} bytes, but got ${copy.length}`,
);
}
//@ts-ignore
Expand All @@ -265,7 +263,7 @@ export class ContractSpec {
return xdr.ScVal.scvBytes(copy);
default:
throw new TypeError(
`invalid type (${ty}) specified for Bytes and BytesN`
`invalid type (${ty}) specified for Bytes and BytesN`,
);
}
}
Expand All @@ -275,19 +273,19 @@ export class ContractSpec {
let vec = ty.vec();
let elementType = vec.elementType();
return xdr.ScVal.scvVec(
val.map((v) => this.nativeToScVal(v, elementType))
val.map((v) => this.nativeToScVal(v, elementType)),
);
}
case xdr.ScSpecType.scSpecTypeTuple().value: {
let tup = ty.tuple();
let valTypes = tup.valueTypes();
if (val.length !== valTypes.length) {
throw new TypeError(
`Tuple expects ${valTypes.length} values, but ${val.length} were provided`
`Tuple expects ${valTypes.length} values, but ${val.length} were provided`,
);
}
return xdr.ScVal.scvVec(
val.map((v, i) => this.nativeToScVal(v, valTypes[i]))
val.map((v, i) => this.nativeToScVal(v, valTypes[i])),
);
}
case xdr.ScSpecType.scSpecTypeMap().value: {
Expand All @@ -299,13 +297,13 @@ export class ContractSpec {
let key = this.nativeToScVal(entry[0], keyType);
let val = this.nativeToScVal(entry[1], valueType);
return new xdr.ScMapEntry({ key, val });
})
}),
);
}

default:
throw new TypeError(
`Type ${ty} was not vec, but value was Array`
`Type ${ty} was not vec, but value was Array`,
);
}
}
Expand All @@ -330,14 +328,13 @@ export class ContractSpec {

if ((val.constructor?.name ?? "") !== "Object") {
throw new TypeError(
`cannot interpret ${
val.constructor?.name
} value as ScVal (${JSON.stringify(val)})`
`cannot interpret ${val.constructor?.name
} value as ScVal (${JSON.stringify(val)})`,
);
}

throw new TypeError(
`Received object ${val} did not match the provided type ${ty}`
`Received object ${val} did not match the provided type ${ty}`,
);
}

Expand Down Expand Up @@ -380,7 +377,7 @@ export class ContractSpec {
return xdr.ScVal.scvVoid();
default:
throw new TypeError(
`Type ${ty} was not void, but value was undefined`
`Type ${ty} was not void, but value was undefined`,
);
}
}
Expand All @@ -399,7 +396,7 @@ export class ContractSpec {
case xdr.ScSpecEntryKind.scSpecEntryUdtEnumV0():
if (typeof val !== "number") {
throw new TypeError(
`expected number for enum ${name}, but got ${typeof val}`
`expected number for enum ${name}, but got ${typeof val}`,
);
}
return this.nativeToEnum(val as number, entry.udtEnumV0());
Expand All @@ -414,7 +411,7 @@ export class ContractSpec {

private nativeToUnion(
val: Union<any>,
union_: xdr.ScSpecUdtUnionV0
union_: xdr.ScSpecUdtUnionV0,
): xdr.ScVal {
let entry_name = val.tag;
let case_ = union_.cases().find((entry) => {
Expand All @@ -434,11 +431,11 @@ export class ContractSpec {
if (Array.isArray(val.values)) {
if (val.values.length != types.length) {
throw new TypeError(
`union ${union_} expects ${types.length} values, but got ${val.values.length}`
`union ${union_} expects ${types.length} values, but got ${val.values.length}`,
);
}
let scvals = val.values.map((v, i) =>
this.nativeToScVal(v, types[i])
this.nativeToScVal(v, types[i]),
);
scvals.unshift(key);
return xdr.ScVal.scvVec(scvals);
Expand All @@ -455,11 +452,11 @@ export class ContractSpec {
if (fields.some(isNumeric)) {
if (!fields.every(isNumeric)) {
throw new Error(
"mixed numeric and non-numeric field names are not allowed"
"mixed numeric and non-numeric field names are not allowed",
);
}
return xdr.ScVal.scvVec(
fields.map((_, i) => this.nativeToScVal(val[i], fields[i].type()))
fields.map((_, i) => this.nativeToScVal(val[i], fields[i].type())),
);
}
return xdr.ScVal.scvMap(
Expand All @@ -469,7 +466,7 @@ export class ContractSpec {
key: this.nativeToScVal(name, xdr.ScSpecTypeDef.scSpecTypeSymbol()),
val: this.nativeToScVal(val[name], field.type()),
});
})
}),
);
}

Expand Down Expand Up @@ -531,13 +528,13 @@ export class ContractSpec {
if (value == xdr.ScSpecType.scSpecTypeVec().value) {
let vec = typeDef.vec();
return (scv.vec() ?? []).map((elm) =>
this.scValToNative(elm, vec.elementType())
this.scValToNative(elm, vec.elementType()),
) as T;
} else if (value == xdr.ScSpecType.scSpecTypeTuple().value) {
let tuple = typeDef.tuple();
let valTypes = tuple.valueTypes();
return (scv.vec() ?? []).map((elm, i) =>
this.scValToNative(elm, valTypes[i])
this.scValToNative(elm, valTypes[i]),
) as T;
}
throw new TypeError(`Type ${typeDef} was not vec, but ${scv} is`);
Expand All @@ -562,8 +559,8 @@ export class ContractSpec {
`ScSpecType ${t.name} was not map, but ${JSON.stringify(
scv,
null,
2
)} is`
2,
)} is`,
);
}

Expand All @@ -581,9 +578,8 @@ export class ContractSpec {
value !== xdr.ScSpecType.scSpecTypeSymbol().value
) {
throw new Error(
`ScSpecType ${
t.name
} was not string or symbol, but ${JSON.stringify(scv, null, 2)} is`
`ScSpecType ${t.name
} was not string or symbol, but ${JSON.stringify(scv, null, 2)} is`,
);
}
return scv.value()?.toString() as T;
Expand All @@ -600,8 +596,8 @@ export class ContractSpec {
`failed to convert ${JSON.stringify(
scv,
null,
2
)} to native type from type ${t.name}`
2,
)} to native type from type ${t.name}`,
);
}
}
Expand All @@ -617,7 +613,7 @@ export class ContractSpec {
return this.unionToNative(scv, entry.udtUnionV0());
default:
throw new Error(
`failed to parse udt ${udt.name().toString()}: ${entry}`
`failed to parse udt ${udt.name().toString()}: ${entry}`,
);
}
}
Expand All @@ -629,7 +625,7 @@ export class ContractSpec {
}
if (vec.length === 0 && udt.cases.length !== 0) {
throw new Error(
`${val} has length 0, but the there are at least one case in the union`
`${val} has length 0, but the there are at least one case in the union`,
);
}
let name = vec[0].sym().toString();
Expand All @@ -639,7 +635,7 @@ export class ContractSpec {
let entry = udt.cases().find(findCase(name));
if (!entry) {
throw new Error(
`failed to find entry ${name} in union {udt.name().toString()}`
`failed to find entry ${name} in union {udt.name().toString()}`,
);
}
let res: Union<any> = { tag: name };
Expand Down Expand Up @@ -667,7 +663,7 @@ export class ContractSpec {
let field = fields[i];
res[field.name().toString()] = this.scValToNative(
entry.val(),
field.type()
field.type(),
);
});
return res;
Expand All @@ -692,7 +688,7 @@ export class ContractSpec {
.filter(
(entry) =>
entry.switch().value ===
xdr.ScSpecEntryKind.scSpecEntryUdtErrorEnumV0().value
xdr.ScSpecEntryKind.scSpecEntryUdtErrorEnumV0().value,
)
.flatMap((entry) => (entry.value() as xdr.ScSpecUdtErrorEnumV0).cases());
}
Expand Down Expand Up @@ -1012,7 +1008,7 @@ function structToJsonSchema(udt: xdr.ScSpecUdtStructV0): object {
if (fields.some(isNumeric)) {
if (!fields.every(isNumeric)) {
throw new Error(
"mixed numeric and non-numeric field names are not allowed"
"mixed numeric and non-numeric field names are not allowed",
);
}
let items = fields.map((_, i) => typeRef(fields[i].type()));
Expand All @@ -1035,7 +1031,7 @@ function structToJsonSchema(udt: xdr.ScSpecUdtStructV0): object {
}

function args_and_required(
input: { type: () => xdr.ScSpecTypeDef; name: () => string | Buffer }[]
input: { type: () => xdr.ScSpecTypeDef; name: () => string | Buffer }[],
): { properties: object; required?: string[] } {
let properties: any = {};
let required: string[] = [];
Expand Down Expand Up @@ -1116,7 +1112,7 @@ function unionToJsonSchema(udt: xdr.ScSpecUdtUnionV0): any {
tag: title,
values: {
type: "array",
items: c.type().map(typeRef)
items: c.type().map(typeRef),
},
},
required: ["tag", "values"],
Expand Down Expand Up @@ -1156,4 +1152,3 @@ function enumToJsonSchema(udt: xdr.ScSpecUdtEnumV0): any {
}
return res;
}

1 change: 0 additions & 1 deletion src/rust_types/index.ts

This file was deleted.

Loading

0 comments on commit 2ee6126

Please sign in to comment.