1+ import Web3 from 'web3' ;
12import { BaseModule } from '../base-module' ;
2- import { createExpectedBearerStringError } from '../../core/sdk-exceptions' ;
3+ import { createExpectedBearerStringError } from '../../core/sdk-exceptions' ;
4+ import { ValidateTokenOwnershipResponse } from '../../types' ;
5+ import { ERC1155ContractABI , ERC721ContractABI } from './ownershipABIs' ;
6+ import { ErrorCode } from '../../types' ;
37
48export class UtilsModule extends BaseModule {
59 /**
@@ -12,4 +16,64 @@ export class UtilsModule extends BaseModule {
1216
1317 return header . substring ( 7 ) ;
1418 }
19+
20+ // Token Gating function validates user ownership of wallet + NFT
21+ public async validateTokenOwnership (
22+ didToken : string ,
23+ contractAddress : string ,
24+ contractType : 'ERC721' | 'ERC1155' ,
25+ web3 : Web3 ,
26+ tokenId ?: string ,
27+ ) : Promise < ValidateTokenOwnershipResponse > {
28+ // Make sure if ERC1155 has a tokenId
29+ if ( contractType === 'ERC1155' && ! tokenId ) {
30+ throw new Error ( 'ERC1155 requires a tokenId' ) ;
31+ }
32+ // Validate DID token
33+ let walletAddress ;
34+ try {
35+ await this . sdk . token . validate ( didToken ) ;
36+ walletAddress = this . sdk . token . getPublicAddress ( didToken ) ;
37+ } catch ( e : any ) {
38+ // Check if code is malformed token
39+ if ( e . code && e . code === 'ERROR_MALFORMED_TOKEN' ) {
40+ return {
41+ valid : false ,
42+ error_code : 'UNAUTHORIZED' ,
43+ message : 'Invalid DID token: ' + ErrorCode . MalformedTokenError ,
44+ } ;
45+ }
46+ if ( e . code === ErrorCode . TokenExpired ) {
47+ return {
48+ valid : false ,
49+ error_code : 'UNAUTHORIZED' ,
50+ message : 'Invalid DID token: ' + ErrorCode . TokenExpired ,
51+ } ;
52+ }
53+ throw new Error ( e ) ;
54+ }
55+
56+
57+ // Check on-chain if user owns NFT by calling contract with web3
58+ let balance = BigInt ( 0 ) ;
59+ if ( contractType === 'ERC721' ) {
60+ const contract = new web3 . eth . Contract ( ERC721ContractABI , contractAddress ) ;
61+ balance = BigInt ( await contract . methods . balanceOf ( walletAddress ) . call ( ) ) ;
62+ } else {
63+ const contract = new web3 . eth . Contract ( ERC1155ContractABI , contractAddress ) ;
64+ balance = BigInt ( await contract . methods . balanceOf ( walletAddress , tokenId ) . call ( ) ) ;
65+ }
66+ if ( balance > BigInt ( 0 ) ) {
67+ return {
68+ valid : true ,
69+ error_code : '' ,
70+ message : '' ,
71+ } ;
72+ }
73+ return {
74+ valid : false ,
75+ error_code : 'NO_OWNERSHIP' ,
76+ message : 'User does not own this token.' ,
77+ } ;
78+ }
1579}
0 commit comments