Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

A breaking change will get clearly marked in this log.

## Unreleased

### Changed
- Generated bindings handle module-qualified user-defined type names. Upcoming versions of `rs-soroban-sdk` name each `#[contracttype]` by its full Rust path ([rs-soroban-sdk#1970](https://github.com/stellar/rs-soroban-sdk/pull/1970)), so a spec entry reads `token::storage::Balance` rather than `Balance`. `types.ts` now declares every type under its whole spec name (`export interface token_storage_Balance`) and additionally exports it under its bare type name (`export type Balance = token_storage_Balance`), so the fully-qualified name is always available while existing code keeps importing and referencing `Balance` as it does today. Enums and error enums are aliased as values (`export { token_DataKey as DataKey }`) so their members stay reachable through either name. Generated signatures and imports use the bare alias where there is one. A bare name is only skipped when the spec makes it ambiguous — several types share it, or another type is declared under it outright — and the declaration's doc comment says so. Resolution is deterministic, so `types.ts` and `client.ts` always agree. Specs with unqualified names generate exactly as before.
- `contract.Spec.findEntry` accepts a bare type name for a module-qualified entry (`findEntry("Balance")` finds `token::storage::Balance`), and throws `ambiguous entry: …` when more than one entry matches.

## [v16.2.0](https://github.com/stellar/js-stellar-sdk/compare/v16.1.0...v16.2.0)

### Added
Expand Down
27 changes: 16 additions & 11 deletions docs/reference/contracts-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -1168,7 +1168,7 @@ errorCases(): ScSpecUdtErrorEnumCaseV0[];

all contract functions

**Source:** [src/contract/spec.ts:1209](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1209)
**Source:** [src/contract/spec.ts:1229](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1229)

### `spec.events()`

Expand All @@ -1182,7 +1182,7 @@ events(): ScSpecEventV0[];

all contract events

**Source:** [src/contract/spec.ts:1224](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1224)
**Source:** [src/contract/spec.ts:1244](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1244)

### `spec.eventTopicFilter(name, topicValues, occurrence)`

Expand Down Expand Up @@ -1219,12 +1219,16 @@ a single topic filter row
const topics = contractSpec.eventTopicFilter('transfer', { to: someAddress });
```

**Source:** [src/contract/spec.ts:1312](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1312)
**Source:** [src/contract/spec.ts:1332](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1332)

### `spec.findEntry(name)`

Finds the XDR spec entry for the given name.

User-defined type names are qualified with the Rust module path they are
declared in (e.g. `token::Balance`), so a bare type name is also accepted
when exactly one entry in the spec ends with it.

```ts
findEntry(name: string): ScSpecEntry;
```
Expand All @@ -1239,9 +1243,10 @@ the entry

**Throws**

- if no entry with the given name exists
- if no entry with the given name exists, or if a bare type name
matches more than one module-qualified entry

**Source:** [src/contract/spec.ts:658](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L658)
**Source:** [src/contract/spec.ts:663](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L663)

### `spec.findEvent(name, occurrence)`

Expand Down Expand Up @@ -1279,7 +1284,7 @@ if (contractSpec.findEvent("transfer")) {
}
```

**Source:** [src/contract/spec.ts:1251](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1251)
**Source:** [src/contract/spec.ts:1271](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1271)

### `spec.funcArgsToScVals(name, args)`

Expand Down Expand Up @@ -1402,7 +1407,7 @@ the converted JSON schema

- if the contract spec is invalid

**Source:** [src/contract/spec.ts:1336](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1336)
**Source:** [src/contract/spec.ts:1356](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1356)

### `spec.nativeToScVal(val, ty)`

Expand All @@ -1425,7 +1430,7 @@ the converted ScVal

- if value cannot be converted to the given type

**Source:** [src/contract/spec.ts:677](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L677)
**Source:** [src/contract/spec.ts:697](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L697)

### `spec.parseEvent(topics, data)`

Expand Down Expand Up @@ -1466,7 +1471,7 @@ if (parsed) {
}
```

**Source:** [src/contract/spec.ts:1283](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1283)
**Source:** [src/contract/spec.ts:1303](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1303)

### `spec.scValStrToNative(scv, typeDef)`

Expand All @@ -1489,7 +1494,7 @@ the converted native JS value

- if ScVal cannot be converted to the given type

**Source:** [src/contract/spec.ts:994](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L994)
**Source:** [src/contract/spec.ts:1014](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1014)

### `spec.scValToNative(scv, typeDef)`

Expand All @@ -1512,7 +1517,7 @@ the converted native JS value

- if ScVal cannot be converted to the given type

**Source:** [src/contract/spec.ts:1007](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1007)
**Source:** [src/contract/spec.ts:1027](https://github.com/stellar/js-stellar-sdk/blob/main/src/contract/spec.ts#L1027)

## contract.Watcher

Expand Down
27 changes: 21 additions & 6 deletions src/bindings/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
formatJSDocComment,
formatImports,
toCamelCase,
createUdtNames,
type UdtNameResolver,
} from "./utils.js";

/**
Expand All @@ -16,6 +18,10 @@ import {
export class ClientGenerator {
private spec: Spec;

// Spec name (module-qualified, e.g. "token::Balance") -> the TypeScript
// identifier types.ts publishes it under. See createUdtNames().
private resolveUdtName: UdtNameResolver;

// event index (in declaration order) -> resolved (possibly disambiguated)
// filter method name. Keyed by index rather than raw name because a
// contract may declare several events with the same name.
Expand All @@ -24,6 +30,7 @@ export class ClientGenerator {

constructor(spec: Spec) {
this.spec = spec;
this.resolveUdtName = createUdtNames(spec.entries).reference;
}

/**
Expand Down Expand Up @@ -99,6 +106,7 @@ ${eventMethods}
const defs = inputs.map((input) => input.type()).concat(outputs);
return defs;
}),
this.resolveUdtName,
);

const events = this.spec.events();
Expand All @@ -119,7 +127,10 @@ ${eventMethods}
.value,
);
topicParams.forEach((param) => {
const nested = generateTypeImports([param.type()]);
const nested = generateTypeImports(
[param.type()],
this.resolveUdtName,
);
nested.typeFileImports.forEach((t) => imports.typeFileImports.add(t));
nested.stellarContractImports.forEach((t) =>
imports.stellarContractImports.add(t),
Expand Down Expand Up @@ -293,7 +304,11 @@ ${eventMethods}
const fieldName = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(rawParamName)
? rawParamName
: `"${escapeStringLiteral(rawParamName)}"`;
const fieldType = parseTypeFromTypeDef(param.type(), true);
const fieldType = parseTypeFromTypeDef(
param.type(),
true,
this.resolveUdtName,
);
return `${fieldName}?: ${fieldType}`;
})
.join("; ");
Expand Down Expand Up @@ -326,11 +341,11 @@ ${eventMethods}
const name = sanitizeIdentifier(func.name().toString());
const inputs = func.inputs().map((input: any) => ({
name: sanitizeIdentifier(input.name().toString()),
type: parseTypeFromTypeDef(input.type(), true),
type: parseTypeFromTypeDef(input.type(), true, this.resolveUdtName),
}));
const outputType =
func.outputs().length > 0
? parseTypeFromTypeDef(func.outputs()[0])
? parseTypeFromTypeDef(func.outputs()[0], false, this.resolveUdtName)
: "void";
const docs = formatJSDocComment(func.doc().toString(), 2);
const params = this.formatMethodParameters(inputs);
Expand All @@ -342,7 +357,7 @@ ${eventMethods}
const name = sanitizeIdentifier(func.name().toString());
const outputType =
func.outputs().length > 0
? parseTypeFromTypeDef(func.outputs()[0])
? parseTypeFromTypeDef(func.outputs()[0], false, this.resolveUdtName)
: "void";

return ` ${name} : this.txFromJSON<${outputType}>`;
Expand All @@ -362,7 +377,7 @@ ${eventMethods}
}
const inputs = constructorFunc.inputs().map((input) => ({
name: sanitizeIdentifier(input.name().toString()),
type: parseTypeFromTypeDef(input.type(), true),
type: parseTypeFromTypeDef(input.type(), true, this.resolveUdtName),
}));

const params = this.formatConstructorParameters(inputs);
Expand Down
Loading
Loading