104 lines
3.0 KiB
TypeScript
104 lines
3.0 KiB
TypeScript
/**
|
|
* Openfort Provider
|
|
*
|
|
* Creates embedded smart wallets for on-ramp users
|
|
* using Openfort's account abstraction SDK.
|
|
*
|
|
* Docs: https://www.openfort.io/docs
|
|
*/
|
|
|
|
import Openfort from '@openfort/openfort-node';
|
|
|
|
export interface OpenfortConfig {
|
|
apiKey: string;
|
|
publishableKey: string;
|
|
chainId: number;
|
|
}
|
|
|
|
export interface WalletInfo {
|
|
playerId: string;
|
|
accountId: string;
|
|
address: string;
|
|
chainId: number;
|
|
}
|
|
|
|
export class OpenfortProvider {
|
|
private client: Openfort;
|
|
private config: OpenfortConfig;
|
|
|
|
constructor(config: OpenfortConfig) {
|
|
this.config = config;
|
|
this.client = new Openfort(config.apiKey);
|
|
}
|
|
|
|
/**
|
|
* Find an existing wallet by player name, or create a new one.
|
|
* Ensures one wallet per label (e.g. "user:alice@example.com").
|
|
*/
|
|
async findOrCreateWallet(label: string, metadata?: Record<string, string>): Promise<WalletInfo> {
|
|
try {
|
|
// Search for existing player by name
|
|
const existing = await this.client.players.list({ name: label, limit: 1 });
|
|
if (existing.data.length > 0) {
|
|
const player = existing.data[0];
|
|
const accounts = await this.client.accounts.v1.list({
|
|
player: player.id,
|
|
chainId: this.config.chainId,
|
|
});
|
|
if (accounts.data.length > 0) {
|
|
const account = accounts.data[0];
|
|
console.log(`[openfort] Found existing wallet: player=${player.id} address=${account.address} label=${label}`);
|
|
return {
|
|
playerId: player.id,
|
|
accountId: account.id,
|
|
address: account.address,
|
|
chainId: this.config.chainId,
|
|
};
|
|
}
|
|
// Player exists but no account on this chain — create one
|
|
const account = await this.client.accounts.v1.create({
|
|
player: player.id,
|
|
chainId: this.config.chainId,
|
|
});
|
|
console.log(`[openfort] Created account for existing player: player=${player.id} address=${account.address}`);
|
|
return {
|
|
playerId: player.id,
|
|
accountId: account.id,
|
|
address: account.address,
|
|
chainId: this.config.chainId,
|
|
};
|
|
}
|
|
|
|
// No existing player — create new
|
|
const player = await this.client.players.create({
|
|
name: label,
|
|
metadata: metadata ?? {},
|
|
});
|
|
|
|
const account = await this.client.accounts.v1.create({
|
|
player: player.id,
|
|
chainId: this.config.chainId,
|
|
});
|
|
|
|
console.log(`[openfort] Created new wallet: player=${player.id} address=${account.address} label=${label}`);
|
|
|
|
return {
|
|
playerId: player.id,
|
|
accountId: account.id,
|
|
address: account.address,
|
|
chainId: this.config.chainId,
|
|
};
|
|
} catch (error) {
|
|
console.error(`[openfort] Failed to find/create wallet for "${label}":`, error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @deprecated Use findOrCreateWallet instead
|
|
*/
|
|
async createWallet(label: string, metadata?: Record<string, string>): Promise<WalletInfo> {
|
|
return this.findOrCreateWallet(label, metadata);
|
|
}
|
|
}
|