Skip to content

Commit

Permalink
Merge pull request #875 from TokenScript/release/3.2.0
Browse files Browse the repository at this point in the history
Release/3.2.0
  • Loading branch information
nicktaras authored Oct 18, 2023
2 parents 91edb19 + 72278b8 commit 62527f5
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 33 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ Feature release including multi-hook support, improved UX for off chain token ho
- Multi-Hook support added
- Added selected token issuer keys to 'tokens-selected' event hook
- Explicitly include ethers library availabilty via Token Negotiator library interface `client.externalUtils.evm.ethers`
- Aligned on chain authentication with off chain user interface (for single token authentication on the client side). Multi token on chain authentication is not yet supported (via the current library features).

### Bug Fixes

- TS interface custom view
- Single token off chain authentication incompatibility interface fix

### Performance / Quality Improvements

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ const negotiator = new Client({
​​
negotiator.negotiate();
​ ​
negotiator.on("tokens-selected", (tokens) => {
console.log('owner tokens found: ', tokens);
negotiator.on("tokens-selected", ({ selectedTokens, selectedIssuerKeys }) => {
console.log('user selected tokens: ', selectedTokens);
});
```
Expand Down
51 changes: 23 additions & 28 deletions src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { MultiTokenAuthRequest, MultiTokenAuthResult, OutletIssuerInterface, Pro
import { AttestationIdClient } from '../outlet/attestationIdClient'
import { EventHookHandler } from './eventHookHandler'
import { ethers } from 'ethers'
import { TokenListItemInterface } from './views/token-list'

if (typeof window !== 'undefined') window.tn = { VERSION }

Expand Down Expand Up @@ -485,7 +486,7 @@ export class Client {
private tokensSelectedCallBackHandler = () => {
this.eventSender('tokens-selected', {
selectedTokens: this.tokenStore.getSelectedTokens(),
selectedTokenKeys: Object.keys(this.tokenStore.getSelectedTokens()),
selectedIssuerKeys: Object.keys(this.tokenStore.getSelectedTokens()),
})
}

Expand Down Expand Up @@ -726,6 +727,7 @@ export class Client {

tokens.map((token) => {
token.walletAddress = walletAddress
token.collectionId = issuer.collectionID
return token
})

Expand Down Expand Up @@ -817,54 +819,45 @@ export class Client {

async prepareToAuthenticateToken(authRequest: AuthenticateInterface) {
await this.checkUserAgentSupport('authentication')
const { unsignedToken, tokenId } = authRequest
if (!authRequest.issuer) authRequest.issuer = unsignedToken?.collectionId
requiredParams(authRequest.issuer && (unsignedToken || tokenId), 'Issuer and unsigned token required.')
const config = this.tokenStore.getCurrentIssuers()[authRequest.issuer]
let unsignedToken = authRequest?.unsignedToken
if (!unsignedToken && authRequest.collectionId) unsignedToken = authRequest
const issuer = authRequest?.issuer ?? unsignedToken?.collectionId ?? authRequest?.collectionId
const tokenId = authRequest?.tokenId
console.log('tokenIssuer', issuer, 'unsignedToken', unsignedToken)
requiredParams(issuer && (unsignedToken || tokenId), 'Issuer and unsigned token required MUTLI.')
const config = this.tokenStore.getCurrentIssuers()[issuer]
if (!config) errorHandler('Provided issuer was not found.', 'error', null, null, true, true)
return authRequest
return { unsignedToken, issuer, tokenId }
}

async getMultiRequestBatch(authRequests: AuthenticateInterface[]) {
let authRequestBatch: { onChain: {}; offChain: { [origin: string]: { [issuer: string]: MultiTokenInterface } } } = {
onChain: {},
offChain: {},
}
// build a list of the batches for each token origin. At this point when this loop is complete
// we will have a list of all the tokens that need to be authenticated and the origin they need to be authenticated against.
await Promise.all(
authRequests.map(async (authRequestItem) => {
const reqItem = await this.prepareToAuthenticateToken(authRequestItem)

if (!reqItem.tokenId && reqItem.unsignedToken?.tokenId) reqItem.tokenId = reqItem.unsignedToken?.tokenId

const issuerConfig = this.tokenStore.getCurrentIssuers()[reqItem.issuer] as OffChainTokenConfig
// Off Chain
// Setup for Token Collection. e.g. authRequestBatch.offChain['https://mywebsite.com']['devcon']
/**
* Always generate a batch
*/
if (issuerConfig.onChain === false) {
if (!authRequestBatch.offChain[issuerConfig.tokenOrigin]) authRequestBatch.offChain[issuerConfig.tokenOrigin] = {}

if (!authRequestBatch.offChain[issuerConfig.tokenOrigin][reqItem.issuer]) {
authRequestBatch.offChain[issuerConfig.tokenOrigin][reqItem.issuer] = {
tokenIds: [],
issuerConfig: issuerConfig,
}
}
// Push token into the request batch
authRequestBatch.offChain[issuerConfig.tokenOrigin][reqItem.issuer].tokenIds.push(reqItem.tokenId)
authRequestBatch.offChain[issuerConfig.tokenOrigin][reqItem.issuer].tokenIds.push(
reqItem.tokenId ?? reqItem.unsignedToken.tokenId,
)
return
}

throw new Error('On-chain token are not supported by batch authentication at this time.')
}),
)

if (Object.keys(authRequestBatch.offChain).length > 1)
if (Object.keys(authRequestBatch.offChain).length > 1) {
throw new Error('Only a single token origin is supported by batch authentication at this time.')

}
return authRequestBatch
}

Expand All @@ -890,7 +883,6 @@ export class Client {
const authRequestBatch = await this.getMultiRequestBatch(authRequests)
let issuerProofs = {}

// Send the request batches to each token origin:
// Off Chain: // ['https://devcon.com']['issuer'][list of tokenIds]
for (const tokenOrigin in authRequestBatch.offChain) {
let AuthType = TicketZKProofMulti
Expand Down Expand Up @@ -933,13 +925,15 @@ export class Client {
else return this.authenticateToken(authRequest as AuthenticateInterface)
}

async authenticateToken(authRequest: AuthenticateInterface) {
async authenticateToken(authRequest: AuthenticateInterface | any) {
await this.checkUserAgentSupport('authentication')

const { unsignedToken, issuer } = authRequest
const tokenIssuer = issuer ?? unsignedToken.collectionId
const tokenIssuer = authRequest.issuer ?? authRequest.unsignedToken?.collectionId ?? authRequest.collectionId
let unsignedToken = authRequest.unsignedToken
if (!unsignedToken && authRequest.collectionId) unsignedToken = authRequest

requiredParams(tokenIssuer && unsignedToken, 'Issuer and unsigned token required.')
console.log('tokenIssuer', tokenIssuer, 'unsignedToken', unsignedToken)
requiredParams(tokenIssuer && unsignedToken, 'Issuer and unsigned token required. SINGLE')

const config = this.tokenStore.getCurrentIssuers()[tokenIssuer]

Expand Down Expand Up @@ -1137,6 +1131,7 @@ export class Client {
if (issuerConfig) this.storeOutletTokenResponse(res.data.tokens)
this.eventSender('tokens-selected', {
selectedTokens: this.tokenStore.getSelectedTokens(),
selectedIssuerKeys: Object.keys(this.tokenStore.getSelectedTokens()),
})
return res.data.tokens
}
Expand Down
2 changes: 2 additions & 0 deletions src/client/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface OnChainTokenConfig extends IssuerConfigInterface {
openSeaSlug?: string
blockchain?: SupportedBlockchainsParam
oAuth2options?: any
abi?: string
}

export interface UltraIssuerConfig extends OnChainTokenConfig {
Expand Down Expand Up @@ -143,6 +144,7 @@ export interface MultiTokenInterface {
}

export interface AuthenticateInterface {
collectionId?: string
issuer: string
tokenId?: number | string
unsignedToken: any
Expand Down
6 changes: 3 additions & 3 deletions src/outlet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,13 @@ export class Outlet extends LocalOutlet {

async sendTokenProof(evtid: string) {
const collectionId: string = this.getDataFromQuery('issuer')
const tokenId: string = this.getDataFromQuery('tokenId')
const token: string = this.getDataFromQuery('tn-token')
const wallet: string = this.getDataFromQuery('wallet')
const address: string = this.getDataFromQuery('address')
const tokenParsed = token ? JSON.parse(token) : undefined
const tokenId = tokenParsed.tokenId ?? this.getDataFromQuery('tokenId')
requiredParams(tokenId, 'tokenId is missing')

const redirect = this.getDataFromQuery('redirect') === 'true' ? window.location.href : false

try {
const issuer = this.getIssuerConfigById(collectionId)

Expand Down

0 comments on commit 62527f5

Please sign in to comment.