Skip to content
Open
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
13 changes: 13 additions & 0 deletions packages/identity-civic/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Config } from '@jest/types';

const config: Config.InitialOptions = {
verbose: true,
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
testRegex: '(.*\\.spec)\\.(jsx?|tsx?)$',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
testTimeout: 60000,
testRunner: 'jasmine2',
};
export default config;
32 changes: 32 additions & 0 deletions packages/identity-civic/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "@dialectlabs/identity-civic",
"version": "0.0.2",
"description": "Civic Identity Resolver",
"repository": "git@github.com:dialectlabs/sdk.git",
"author": "Kevin Colgan",
"license": "Apache-2.0",
"main": "./lib/cjs/index.js",
"module": "./lib/esm/index.js",
"types": "./lib/types/index.d.ts",
"exports": {
"import": "./lib/esm/index.js",
"require": "./lib/cjs/index.js"
},
"scripts": {
"clean": "rm -rf lib",
"build": "npm run clean && npm run build:cjs; npm run build:esm",
"build:cjs": "tsc --project tsconfig.cjs.json",
"build:cjs:watch": "concurrently \"tsc --project tsconfig.cjs.json --watch\"",
"build:esm": "tsc --project tsconfig.esm.json",
"build:esm:watch": "concurrently \"tsc --project tsconfig.esm.json --watch\"",
"dev": "yarn clean && concurrently \"npm:build:cjs:watch\" \"npm:build:esm:watch\"",
"test": "jest"
},
"peerDependencies": {
"@dialectlabs/sdk": "*",
"@solana/web3.js": "1.x"
},
"dependencies": {
"@civic/profile": "^0.0.3"
}
}
41 changes: 41 additions & 0 deletions packages/identity-civic/src/identity-civic.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Connection, PublicKey } from '@solana/web3.js';
import { CivicIdentityResolver } from './identity-civic';

const RPC_URL = 'https://api.mainnet-beta.solana.com';
const connection = new Connection(RPC_URL);

describe('Civic tests', () => {
it('should perform direct lookup', async () => {
const resolver = new CivicIdentityResolver(connection);
const owner = new PublicKey('4Gh3VaUQ5iR7YuqJFBzHZJ95owganwfBidDCNf9RE7cE');
const identity = await resolver.resolve(owner);

expect(identity).toStrictEqual({
type: 'CIVIC',
name: 'my.nfts',
publicKey: owner,
additionals: {
avatarUrl: 'https://arweave.net/C3oH-InR6fqeqN62TQOI5LnQqNXDmboRK75xFIIT3fU',
link: `https://www.civic.me/${owner.toBase58()}`,
headline: 'this is my headline'
},
});
});

it('should perform a reverse lookup from a .sol address', async () => {
const resolver = new CivicIdentityResolver(connection);
const owner = new PublicKey('BriW4tTAiAm541uB2Fua3dUNoGayRa8Wt7pZUshUbrPB');
const identity = await resolver.resolveReverse('solana.sol');

expect(identity).toStrictEqual({
type: 'CIVIC',
name: '',
publicKey: owner,
additionals: {
avatarUrl: undefined,
link: `https://www.civic.me/${owner.toBase58()}`,
headline: undefined
},
});
});
});
40 changes: 40 additions & 0 deletions packages/identity-civic/src/identity-civic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { CivicProfile, ProfileResult } from '@civic/profile';
import type { Identity, IdentityResolver } from '@dialectlabs/sdk';
import type { Connection } from '@solana/web3.js';
import { PublicKey } from '@solana/web3.js';

const civicType = 'CIVIC';
const civicProfileToDialectIdentity = (
profile: ProfileResult,
defaultName = '',
): Identity => {
return {
name: profile?.name?.value || defaultName,
publicKey: new PublicKey(profile.address),
type: civicType,
additionals: {
avatarUrl: profile.image?.url,
link: `https://www.civic.me/${profile.address}`,
headline: profile.headline?.value,
},
};
};
export class CivicIdentityResolver implements IdentityResolver {
constructor(private readonly connection: Connection) {}
get type(): string {
return civicType;
}

async resolve(publicKey: PublicKey): Promise<Identity | null> {
const profile = await CivicProfile.get(publicKey.toBase58(), {
solana: { connection: this.connection },
});
return civicProfileToDialectIdentity(profile);
}

async resolveReverse(_rawDomainName: string): Promise<Identity | null> {
// CivicProfile supports other non-public key type queries like Bonfida addresses
const profile = await CivicProfile.get(_rawDomainName);
return civicProfileToDialectIdentity(profile);
}
}
1 change: 1 addition & 0 deletions packages/identity-civic/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './identity-civic';
18 changes: 18 additions & 0 deletions packages/identity-civic/tsconfig.cjs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"target": "ES6",
"module": "CommonJS",
"outDir": "lib/cjs",
"declarationDir": "lib/types"
},
"rootDir": "./src",
"include": ["src/**/*.ts"],
"exclude": [
"src/**/*.spec.ts",
"src/**/*.test.ts",
"tests/**/*.test.ts",
"tests/**/*.spec.ts"
]
}
17 changes: 17 additions & 0 deletions packages/identity-civic/tsconfig.esm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"module": "ESNext",
"outDir": "lib/esm",
"declarationDir": "lib/types"
},
"rootDir": "./src",
"include": ["src/**/*.ts"],
"exclude": [
"src/**/*.spec.ts",
"src/**/*.test.ts",
"tests/**/*.test.ts",
"tests/**/*.spec.ts"
]
}
8 changes: 8 additions & 0 deletions packages/identity-civic/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": "./src"
},
"rootDir": "./src",
"include": ["src/**/*.ts", "tests/**/*.ts"]
}
Loading