All files account-creator.ts

91.89% Statements 34/37
77.27% Branches 17/22
88.88% Functions 8/9
94.28% Lines 33/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 9529x                               1x               3x 3x 3x 3x   3x       3x 3x     3x 3x   3x 3x                         3x 3x 3x 3x 2x 2x   2x     2x       3x   3x 1x 1x   1x             3x   3x       3x 3x   3x 3x   1x  
import {ChainId, Name, NameType} from '@wharfkit/session'
import type {CallbackPayload, ChainIdType} from '@wharfkit/session'
 
export interface AccountCreationOptions {
    scope: NameType
    supportedChains?: ChainIdType[]
    creationServiceUrl?: string
    returnUrl?: string
}
 
export interface AccountCreationErrorResponse {
    error: string
}
 
export type AccountCreationResponse = CallbackPayload & AccountCreationErrorResponse
 
export class AccountCreator {
    private popupWindow?: Window
    private scope?: Name
    private supportedChains: ChainId[]
    private creationServiceUrl: string
    // private returnUrl: string
    private popupStatusInterval?: ReturnType<typeof setInterval>
 
    constructor(public readonly options: AccountCreationOptions) {
        this.supportedChains = (options.supportedChains || []).map((id) => ChainId.from(id))
        if (options.scope) {
            this.scope = Name.from(options.scope)
        }
        this.creationServiceUrl = options.creationServiceUrl || 'https://create.anchor.link'
    }
 
    async createAccount(): Promise<AccountCreationResponse> {
        const qs = new URLSearchParams()
        Iif (this.supportedChains.length > 0) {
            qs.set('supported_chains', this.supportedChains.map(String).join(','))
        }
        if (this.scope) {
            qs.set('scope', String(this.scope))
        }
        const url = `${this.creationServiceUrl}/create?${qs}`
        this.popupWindow = window.open(
            url,
            'targetWindow',
            `toolbar=no,
            location=no,
            status=no,
            menubar=no,
            scrollbars=yes,
            resizable=yes,
            width=400,
            height=600`
        )!
 
        return new Promise((resolve, reject) => {
            const origin = new URL(this.creationServiceUrl).origin
            const listener = (event: MessageEvent) => {
                if (event.origin === origin) {
                    window.removeEventListener('message', listener)
                    this.closeDialog()
 
                    Iif (event.data.error) {
                        reject(new Error(event.data.error))
                    } else {
                        resolve(event.data)
                    }
                }
            }
            window.addEventListener('message', listener)
 
            this.popupStatusInterval = setInterval(() => {
                if (this.popupWindow && this.popupWindow.closed) {
                    this.closeDialog()
 
                    reject(new Error('Popup window closed'))
                }
            }, 500)
        })
    }
 
    closeDialog() {
        this.popupWindow?.close()
 
        this.cleanup()
    }
 
    cleanup() {
        if (this.popupStatusInterval) {
            clearInterval(this.popupStatusInterval)
        }
        this.popupStatusInterval = undefined
        this.popupWindow = undefined
    }
}