Skip to content
Merged
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
16 changes: 15 additions & 1 deletion core/ledger-client/src/token-standard-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1268,14 +1268,28 @@ export class TokenStandardService {
return [exercise, disclosed]
}

async getInstrumentAdmin(registryUrl: string): Promise<string | undefined> {
async getInstrumentAdmin(registryUrl: string): Promise<string> {
const client = this.core.getTokenStandardClient(registryUrl)

const info = await client.get('/registry/metadata/v1/info')

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 }),
},
})
}

// <T> is shape of viewValue related to queried interface.
// i.e. when querying by TransferInstruction interfaceId, <T> would be TransferInstructionView from daml codegen
async listContractsByInterface<T = ViewValue>(
Expand Down
4 changes: 2 additions & 2 deletions core/token-standard/src/token-standard-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export class TokenStandardClient {
body: PostRequest<Path>,
params?: {
path?: Record<string, string>
query?: Record<string, string>
query?: Record<string, string | number>
}
): Promise<PostResponse<Path>> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)
Expand All @@ -116,7 +116,7 @@ export class TokenStandardClient {
path: Path,
params?: {
path?: Record<string, string>
query?: Record<string, string>
query?: Record<string, string | number>
}
): Promise<GetResponse<Path>> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)
Expand Down
96 changes: 67 additions & 29 deletions sdk/wallet-sdk/src/tokenStandardController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,40 @@ export class TokenStandardController {
else return this.transferFactoryRegistryUrl
}

async getInstrumentAdmin(): Promise<PartyId | undefined> {
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<PartyId> {
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.
Expand Down Expand Up @@ -382,10 +409,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)
Expand Down Expand Up @@ -577,15 +601,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
)
Expand All @@ -606,13 +632,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
)
Expand Down Expand Up @@ -735,7 +763,7 @@ export class TokenStandardController {
amount: string,
instrument: {
instrumentId: string
instrumentAdmin: PartyId
instrumentAdmin?: PartyId
},
inputUtxos?: string[],
memo?: string,
Expand All @@ -749,12 +777,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,
Expand Down Expand Up @@ -864,7 +894,7 @@ export class TokenStandardController {
amount: string,
instrument: {
instrumentId: string
instrumentAdmin: PartyId
instrumentAdmin?: PartyId
},
inputUtxos?: string[],
memo?: string,
Expand All @@ -874,12 +904,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,
Expand All @@ -898,13 +930,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.
Expand All @@ -918,7 +950,7 @@ export class TokenStandardController {
receiver: PartyId,
amount: string,
instrumentId: string,
instrumentAdmin: PartyId,
instrumentAdmin: PartyId | undefined,
beneficiaries: Beneficiaries[],
inputUtxos?: string[],
memo?: string,
Expand All @@ -927,12 +959,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,
Expand All @@ -949,15 +983,15 @@ 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
* @returns Wrapped ExerciseCommand and disclosed contracts for submission
*/
async createAllocationInstruction(
allocationSpecification: AllocationSpecification,
expectedAdmin: PartyId,
expectedAdmin?: PartyId,
inputUtxos?: string[],
requestedAt?: string,
prefetchedRegistryChoiceContext?: {
Expand All @@ -968,10 +1002,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,
Expand All @@ -992,24 +1028,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
)
Expand Down
Loading