From 92f4eee9d6d2eda4658cd560030217cde4b536a7 Mon Sep 17 00:00:00 2001 From: Pawel Stepien Date: Fri, 7 Nov 2025 15:01:15 +0100 Subject: [PATCH] handle failed, refine, fixtures to json Signed-off-by: Pawel Stepien --- .../src/token-standard-service.ts | 16 +++- .../src/token-standard-client.ts | 4 +- sdk/wallet-sdk/src/tokenStandardController.ts | 96 +++++++++++++------ 3 files changed, 84 insertions(+), 32 deletions(-) diff --git a/core/ledger-client/src/token-standard-service.ts b/core/ledger-client/src/token-standard-service.ts index 4efe68526..3c1a75602 100644 --- a/core/ledger-client/src/token-standard-service.ts +++ b/core/ledger-client/src/token-standard-service.ts @@ -1195,7 +1195,7 @@ export class TokenStandardService { } } - async getInstrumentAdmin(registryUrl: string): Promise { + async getInstrumentAdmin(registryUrl: string): Promise { const client = this.core.getTokenStandardClient(registryUrl) const info = await client.get('/registry/metadata/v1/info') @@ -1203,6 +1203,20 @@ export class TokenStandardService { return info.adminId } + async listInstruments( + registryUrl: string, + pageSize?: number, + pageToken?: string + ) { + const client = this.core.getTokenStandardClient(registryUrl) + return client.get('/registry/metadata/v1/instruments', { + query: { + ...(pageSize && { pageSize }), + ...(pageToken && { pageToken }), + }, + }) + } + // is shape of viewValue related to queried interface. // i.e. when querying by TransferInstruction interfaceId, would be TransferInstructionView from daml codegen async listContractsByInterface( diff --git a/core/token-standard/src/token-standard-client.ts b/core/token-standard/src/token-standard-client.ts index 6e5f3edf9..e4f1cb773 100644 --- a/core/token-standard/src/token-standard-client.ts +++ b/core/token-standard/src/token-standard-client.ts @@ -101,7 +101,7 @@ export class TokenStandardClient { body: PostRequest, params?: { path?: Record - query?: Record + query?: Record } ): Promise> { // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:) @@ -116,7 +116,7 @@ export class TokenStandardClient { path: Path, params?: { path?: Record - query?: Record + query?: Record } ): Promise> { // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:) diff --git a/sdk/wallet-sdk/src/tokenStandardController.ts b/sdk/wallet-sdk/src/tokenStandardController.ts index af58e296c..a247b4e84 100644 --- a/sdk/wallet-sdk/src/tokenStandardController.ts +++ b/sdk/wallet-sdk/src/tokenStandardController.ts @@ -170,13 +170,40 @@ export class TokenStandardController { else return this.transferFactoryRegistryUrl } - async getInstrumentAdmin(): Promise { - const instrumentAdmin: string | undefined = - await this.service.getInstrumentAdmin( - this.getTransferFactoryRegistryUrl().href - ) - if (instrumentAdmin) return instrumentAdmin as PartyId - else return undefined + /** + * Gets partyId of instrument admin from currently set registry URL + * @returns partyId of instrumentAdmin + */ + async getInstrumentAdmin(): Promise { + return this.service.getInstrumentAdmin( + this.getTransferFactoryRegistryUrl().href + ) + } + + /** + * Gets metadata of an instrument + * @param instrumentId ID of the instrument + * @returns metadata of the instrument + */ + async getInstrumentById(instrumentId: string) { + return this.service.getInstrumentById( + this.getTransferFactoryRegistryUrl().href, + instrumentId + ) + } + + /** + * Lists instruments and metadata available on the registry + * @param pageSize Optional Number of instruments per page + * @param pageToken Optional The `nextPageToken` received from the response for the previous page + * @returns metadata of the instrument + */ + async listInstruments(pageSize?: number, pageToken?: string) { + return this.service.listInstruments( + this.getTransferFactoryRegistryUrl().href, + pageSize, + pageToken + ) } /** Lists all holdings for the current party. @@ -347,10 +374,7 @@ export class TokenStandardController { | undefined > { try { - await this.service.getInstrumentById( - this.getTransferFactoryRegistryUrl().href, - instrumentId - ) + await this.getInstrumentById(instrumentId) const transfer_preapproval = await this.service.getTransferPreApprovalByParty(receiverId) @@ -542,15 +566,17 @@ export class TokenStandardController { amount: string, instrument: { instrumentId: string - instrumentAdmin: PartyId + instrumentAdmin?: PartyId } ): Promise< [WrappedCommand<'ExerciseCommand'>, Types['DisclosedContract'][]] > { + const instrumentAdmin = + instrument.instrumentAdmin ?? (await this.getInstrumentAdmin()) const [tapCommand, disclosedContracts] = await this.service.createTap( receiver, amount, - instrument.instrumentAdmin, + instrumentAdmin, instrument.instrumentId, this.getTransferFactoryRegistryUrl().href ) @@ -571,13 +597,15 @@ export class TokenStandardController { amount: string, instrument: { instrumentId: string - instrumentAdmin: PartyId + instrumentAdmin?: PartyId } ) { + const instrumentAdmin = + instrument.instrumentAdmin ?? (await this.getInstrumentAdmin()) const [tapCommand, disclosedContracts] = await this.service.createTap( receiver, amount, - instrument.instrumentAdmin, + instrumentAdmin, instrument.instrumentId, this.getTransferFactoryRegistryUrl().href ) @@ -700,7 +728,7 @@ export class TokenStandardController { amount: string, instrument: { instrumentId: string - instrumentAdmin: PartyId + instrumentAdmin?: PartyId }, inputUtxos?: string[], memo?: string, @@ -714,12 +742,14 @@ export class TokenStandardController { [WrappedCommand<'ExerciseCommand'>, Types['DisclosedContract'][]] > { try { + const instrumentAdmin = + instrument.instrumentAdmin ?? (await this.getInstrumentAdmin()) const [transferCommand, disclosedContracts] = await this.service.transfer.createTransfer( sender, receiver, amount, - instrument.instrumentAdmin, + instrumentAdmin, instrument.instrumentId, this.getTransferFactoryRegistryUrl().href, inputUtxos, @@ -829,7 +859,7 @@ export class TokenStandardController { amount: string, instrument: { instrumentId: string - instrumentAdmin: PartyId + instrumentAdmin?: PartyId }, inputUtxos?: string[], memo?: string, @@ -839,12 +869,14 @@ export class TokenStandardController { transferInstructionRegistryTypes['schemas']['TransferFactoryWithChoiceContext'] > { try { + const instrumentAdmin = + instrument.instrumentAdmin ?? (await this.getInstrumentAdmin()) const choiceArgs = await this.service.transfer.buildTransferChoiceArgs( sender, receiver, amount, - instrument.instrumentAdmin, + instrumentAdmin, instrument.instrumentId, inputUtxos, memo, @@ -863,13 +895,13 @@ export class TokenStandardController { /** * Creates a new transfer for the specified sender, receiver, amount, and instrument using a delegate proxy. - * @param exchangeParty delegate interacting with token standard workflow * @param proxyCid contract id for the DelegateProxy contract created for the exchange party * @param featuredAppRightCid The featured app right contract of the provider * @param sender The party of the sender. * @param receiver The party of the receiver. * @param amount The amount to be transferred. - * @param instrument The instrument to be used for the transfer. + * @param instrumentId The instrument to be used for the transfer. + * @param instrumentAdmin Instrument admin's party ID, if omitted it will be fetched from registry. * @param inputUtxos The utxos to use for this transfer, if not defined it will auto-select. * @param memo The message for the receiver to identify the transaction. * @param expiryDate Optional Expiry Date, default is 24 hours. @@ -883,7 +915,7 @@ export class TokenStandardController { receiver: PartyId, amount: string, instrumentId: string, - instrumentAdmin: PartyId, + instrumentAdmin: PartyId | undefined, beneficiaries: Beneficiaries[], inputUtxos?: string[], memo?: string, @@ -892,12 +924,14 @@ export class TokenStandardController { ): Promise< [WrappedCommand<'ExerciseCommand'>, Types['DisclosedContract'][]] > { + const _instrumentAdmin = + instrumentAdmin ?? (await this.getInstrumentAdmin()) const [exercise, disclosedContracts] = await this.service.createDelegateProxyTranfser( sender, receiver, amount, - instrumentAdmin, + _instrumentAdmin, instrumentId, this.getTransferFactoryRegistryUrl().href, featuredAppRightCid, @@ -914,7 +948,7 @@ export class TokenStandardController { /** * Creates an allocation instruction (optionally using pre-fetched registry choice context) * @param allocationSpecification Allocation specification to request - * @param expectedAdmin Expected registry admin + * @param expectedAdmin Optional Expected registry admin, if not provided it will be fetched from registry * @param inputUtxos Optional specific UTXOs to consume; auto-selected if omitted * @param requestedAt Optional request timestamp (ISO string) * @param prefetchedRegistryChoiceContext Optional factory id + choice context to avoid a registry call @@ -922,7 +956,7 @@ export class TokenStandardController { */ async createAllocationInstruction( allocationSpecification: AllocationSpecification, - expectedAdmin: PartyId, + expectedAdmin?: PartyId, inputUtxos?: string[], requestedAt?: string, prefetchedRegistryChoiceContext?: { @@ -933,10 +967,12 @@ export class TokenStandardController { [WrappedCommand<'ExerciseCommand'>, Types['DisclosedContract'][]] > { try { + const _expectedAdmin = + expectedAdmin ?? (await this.getInstrumentAdmin()) const [exercise, disclosed] = await this.service.allocation.createAllocationInstruction( allocationSpecification, - expectedAdmin, + _expectedAdmin, this.getTransferFactoryRegistryUrl().href, inputUtxos, requestedAt, @@ -957,24 +993,26 @@ export class TokenStandardController { * Builds and fetches the registry context for an allocation factory call * Use this to prefetch context for offline signing * @param allocationSpecification Allocation specification to request - * @param expectedAdmin Expected registry admin + * @param expectedAdmin Optional Expected registry admin, if not provided it will be fetched from registry * @param inputUtxos Optional specific UTXOs to consume; auto-selected if omitted * @param requestedAt Optional request timestamp (ISO string) * @returns Allocation factory id + choice context from the registry */ async getCreateAllocationInstructionContext( allocationSpecification: AllocationSpecification, - expectedAdmin: PartyId, + expectedAdmin?: PartyId, inputUtxos?: string[], requestedAt?: string ): Promise< allocationInstructionRegistryTypes['schemas']['FactoryWithChoiceContext'] > { try { + const _expectedAdmin = + expectedAdmin ?? (await this.getInstrumentAdmin()) const choiceArgs = await this.service.allocation.buildAllocationFactoryChoiceArgs( allocationSpecification, - expectedAdmin, + _expectedAdmin, inputUtxos, requestedAt )